diff --git a/packages/svelte/src/internal/client/custom-renderer/index.js b/packages/svelte/src/internal/client/custom-renderer/index.js index b7ade121f8..e6ea2e29b5 100644 --- a/packages/svelte/src/internal/client/custom-renderer/index.js +++ b/packages/svelte/src/internal/client/custom-renderer/index.js @@ -6,20 +6,28 @@ import { push_renderer } from './state'; * @template [TElement=any] * @template [TTextNode=any] * @template [TComment=any] - * @template [TNode=TElement | TTextNode | TComment | TFragment] + * @template [TNode=TFragment | TElement | TTextNode | TComment] * @typedef {Object} Renderer - * @property {()=>TFragment} createFragment - * @property {(name: string)=>TElement} createElement - * @property {(data: string)=>TTextNode} createTextNode - * @property {(element: TElement, key: string, value: any)=>void} setAttribute - * @property {(node: TNode, text: string)=>void} setText - * @property {(data: string)=>TComment} createComment - * @property {(element: TNode)=>TNode} getFirstChild - * @property {(element: TNode)=>TNode} getLastChild - * @property {(element: TNode)=>TNode} getNextSibling - * @property {(parent: TNode, element: TNode, anchor: TNode | null)=>void} insert - * @property {(node: TNode)=>void} remove - * @property {(element: TNode)=>TNode} getParent + * @property {()=>TFragment} createFragment - Creates a fragment, a container for multiple nodes. Inserting a fragment should insert all of it's children. + * @property {(name: string)=>TElement} createElement - Creates an element with the given name. + * @property {(data: string)=>TTextNode} createTextNode - Creates a text node with the given data. + * @property {(data: string)=>TComment} createComment - Creates a comment node with the given data. This is often used as an anchor for inserting elements, it doesn't necessarily need to be rendered + * @property {(node: TNode)=> "fragment" | "element" | "text" | "comment"} nodeType - Should return the type of the node in string form ("fragment", "element", "text", "comment"). + * @property {(node: TNode)=>string | null} getNodeValue - Return the value of the node...this should be the text value of a text node, the data value of a comment, null for elements and fragments + * @property {(element: TElement, name: string)=>string | null} getAttribute - Return the value of the attribute with the given name on the element, or null if it doesn't exist + * @property {(element: TElement, key: string, value: any)=>void} setAttribute - Set the attribute with the given name and value on the element + * @property {(element: TElement, name: string)=>void} removeAttribute - Remove the attribute with the given name from the element + * @property {(element: TElement, name: string)=>boolean} hasAttribute - Return true if the element has an attribute with the given name + * @property {(node: TNode, text: string)=>void} setText - Set the text content of the node to the given value. This should work for both text nodes and elements (setting text content on an element should replace all of it's children with a single text node) + * @property {(element: TElement | TFragment)=>TNode} getFirstChild - Return the first child of the element, or null if it has no children. This should work for both elements and fragments + * @property {(element: TElement | TFragment)=>TNode} getLastChild - Return the last child of the element, or null if it has no children. This should work for both elements and fragments + * @property {(element: TNode)=>TNode} getNextSibling - Return the next sibling of the node, or null if it has no next sibling + * @property {(parent: TElement | TFragment, element: TNode, anchor: TNode | null)=>void} insert - Insert the element into the parent before the anchor (if the anchor is null, insert at the end). This should work for both elements and fragments as parents + * @property {(node: TNode)=>void} remove - Remove the node from the tree + * @property {(element: TNode)=>TNode} getParent - Return the parent of the element, or null if it has no parent + * @property {(node: TNode, deep: boolean)=>TNode} cloneNode - Return a clone of the node. If deep is true, all of the node's children should also be cloned + * @property {(target: TNode, type: string, handler: any, options?: any)=>void} addEventListener - Add an event listener of the given type and handler to the target node, with optional options + * @property {(target: TNode, type: string, handler: any, options?: any)=>void} removeEventListener - Remove an event listener of the given type and handler from the target node, with optional options */ /** @@ -28,7 +36,7 @@ import { push_renderer } from './state'; * @template [const TTextNode=unknown] * @template [const TComment=unknown] * @param {Renderer} renderer - * @returns {Renderer & { render: (Component: any, options: { target: TNode, props?: any }) => () => void }} + * @returns {Renderer & { render: (Component: any, options: { target: TFragment | TElement | TTextNode | TComment, props?: any }) => () => void }} */ export function createRenderer(renderer) { return { diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 51b9d079f4..4b73972af1 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -2568,7 +2568,94 @@ declare module 'svelte/reactivity/window' { } declare module 'svelte/renderer' { - export function createRenderer(renderer: any): any; + export function createRenderer(renderer: Renderer): Renderer & { + render: (Component: any, options: { + target: TFragment | TElement | TTextNode | TComment; + props?: any; + }) => () => void; + }; + export type Renderer = { + /** + * - Creates a fragment, a container for multiple nodes. Inserting a fragment should insert all of it's children. + */ + createFragment: () => TFragment; + /** + * - Creates an element with the given name. + */ + createElement: (name: string) => TElement; + /** + * - Creates a text node with the given data. + */ + createTextNode: (data: string) => TTextNode; + /** + * - Creates a comment node with the given data. This is often used as an anchor for inserting elements, it doesn't necessarily need to be rendered + */ + createComment: (data: string) => TComment; + /** + * - Should return the type of the node in string form ("fragment", "element", "text", "comment"). + */ + nodeType: (node: TNode) => "fragment" | "element" | "text" | "comment"; + /** + * - Return the value of the node...this should be the text value of a text node, the data value of a comment, null for elements and fragments + */ + getNodeValue: (node: TNode) => string | null; + /** + * - Return the value of the attribute with the given name on the element, or null if it doesn't exist + */ + getAttribute: (element: TElement, name: string) => string | null; + /** + * - Set the attribute with the given name and value on the element + */ + setAttribute: (element: TElement, key: string, value: any) => void; + /** + * - Remove the attribute with the given name from the element + */ + removeAttribute: (element: TElement, name: string) => void; + /** + * - Return true if the element has an attribute with the given name + */ + hasAttribute: (element: TElement, name: string) => boolean; + /** + * - Set the text content of the node to the given value. This should work for both text nodes and elements (setting text content on an element should replace all of it's children with a single text node) + */ + setText: (node: TNode, text: string) => void; + /** + * - Return the first child of the element, or null if it has no children. This should work for both elements and fragments + */ + getFirstChild: (element: TElement | TFragment) => TNode; + /** + * - Return the last child of the element, or null if it has no children. This should work for both elements and fragments + */ + getLastChild: (element: TElement | TFragment) => TNode; + /** + * - Return the next sibling of the node, or null if it has no next sibling + */ + getNextSibling: (element: TNode) => TNode; + /** + * - Insert the element into the parent before the anchor (if the anchor is null, insert at the end). This should work for both elements and fragments as parents + */ + insert: (parent: TElement | TFragment, element: TNode, anchor: TNode | null) => void; + /** + * - Remove the node from the tree + */ + remove: (node: TNode) => void; + /** + * - Return the parent of the element, or null if it has no parent + */ + getParent: (element: TNode) => TNode; + /** + * - Return a clone of the node. If deep is true, all of the node's children should also be cloned + */ + cloneNode: (node: TNode, deep: boolean) => TNode; + /** + * - Add an event listener of the given type and handler to the target node, with optional options + */ + addEventListener: (target: TNode, type: string, handler: any, options?: any) => void; + /** + * - Remove an event listener of the given type and handler from the target node, with optional options + */ + removeEventListener: (target: TNode, type: string, handler: any, options?: any) => void; + }; export {}; }