UNPKG

9.81 kBSource Map (JSON)View Raw
1{"version":3,"file":"directive-helpers.js","sources":["src/directive-helpers.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nimport {_$LH, Part, DirectiveParent, TemplateResult} from './lit-html.js';\nimport {\n DirectiveResult,\n DirectiveClass,\n PartInfo,\n AttributePartInfo,\n} from './directive.js';\ntype Primitive = null | undefined | boolean | number | string | symbol | bigint;\n\nconst {_ChildPart: ChildPart} = _$LH;\n\ntype ChildPart = InstanceType<typeof ChildPart>;\n\nconst ENABLE_SHADYDOM_NOPATCH = true;\n\nconst wrap =\n ENABLE_SHADYDOM_NOPATCH &&\n window.ShadyDOM?.inUse &&\n window.ShadyDOM?.noPatch === true\n ? window.ShadyDOM!.wrap\n : (node: Node) => node;\n\n/**\n * Tests if a value is a primitive value.\n *\n * See https://tc39.github.io/ecma262/#sec-typeof-operator\n */\nexport const isPrimitive = (value: unknown): value is Primitive =>\n value === null || (typeof value != 'object' && typeof value != 'function');\n\nexport const TemplateResultType = {\n HTML: 1,\n SVG: 2,\n} as const;\n\nexport type TemplateResultType =\n typeof TemplateResultType[keyof typeof TemplateResultType];\n\n/**\n * Tests if a value is a TemplateResult.\n */\nexport const isTemplateResult = (\n value: unknown,\n type?: TemplateResultType\n): value is TemplateResult =>\n type === undefined\n ? // This property needs to remain unminified.\n (value as TemplateResult)?.['_$litType$'] !== undefined\n : (value as TemplateResult)?.['_$litType$'] === type;\n\n/**\n * Tests if a value is a DirectiveResult.\n */\nexport const isDirectiveResult = (value: unknown): value is DirectiveResult =>\n // This property needs to remain unminified.\n (value as DirectiveResult)?.['_$litDirective$'] !== undefined;\n\n/**\n * Retrieves the Directive class for a DirectiveResult\n */\nexport const getDirectiveClass = (value: unknown): DirectiveClass | undefined =>\n // This property needs to remain unminified.\n (value as DirectiveResult)?.['_$litDirective$'];\n\n/**\n * Tests whether a part has only a single-expression with no strings to\n * interpolate between.\n *\n * Only AttributePart and PropertyPart can have multiple expressions.\n * Multi-expression parts have a `strings` property and single-expression\n * parts do not.\n */\nexport const isSingleExpression = (part: PartInfo) =>\n (part as AttributePartInfo).strings === undefined;\n\nconst createMarker = () => document.createComment('');\n\n/**\n * Inserts a ChildPart into the given container ChildPart's DOM, either at the\n * end of the container ChildPart, or before the optional `refPart`.\n *\n * This does not add the part to the containerPart's committed value. That must\n * be done by callers.\n *\n * @param containerPart Part within which to add the new ChildPart\n * @param refPart Part before which to add the new ChildPart; when omitted the\n * part added to the end of the `containerPart`\n * @param part Part to insert, or undefined to create a new part\n */\nexport const insertPart = (\n containerPart: ChildPart,\n refPart?: ChildPart,\n part?: ChildPart\n): ChildPart => {\n const container = wrap(containerPart._$startNode).parentNode!;\n\n const refNode =\n refPart === undefined ? containerPart._$endNode : refPart._$startNode;\n\n if (part === undefined) {\n const startNode = wrap(container).insertBefore(createMarker(), refNode);\n const endNode = wrap(container).insertBefore(createMarker(), refNode);\n part = new ChildPart(\n startNode,\n endNode,\n containerPart,\n containerPart.options\n );\n } else {\n const endNode = wrap(part._$endNode!).nextSibling;\n const oldParent = part._$parent;\n const parentChanged = oldParent !== containerPart;\n if (parentChanged) {\n part._$reparentDisconnectables?.(containerPart);\n // Note that although `_$reparentDisconnectables` updates the part's\n // `_$parent` reference after unlinking from its current parent, that\n // method only exists if Disconnectables are present, so we need to\n // unconditionally set it here\n part._$parent = containerPart;\n // Since the _$isConnected getter is somewhat costly, only\n // read it once we know the subtree has directives that need\n // to be notified\n let newConnectionState;\n if (\n part._$notifyConnectionChanged !== undefined &&\n (newConnectionState = containerPart._$isConnected) !==\n oldParent!._$isConnected\n ) {\n part._$notifyConnectionChanged(newConnectionState);\n }\n }\n if (endNode !== refNode || parentChanged) {\n let start: Node | null = part._$startNode;\n while (start !== endNode) {\n const n: Node | null = wrap(start!).nextSibling;\n wrap(container).insertBefore(start!, refNode);\n start = n;\n }\n }\n }\n\n return part;\n};\n\n/**\n * Sets the value of a Part.\n *\n * Note that this should only be used to set/update the value of user-created\n * parts (i.e. those created using `insertPart`); it should not be used\n * by directives to set the value of the directive's container part. Directives\n * should return a value from `update`/`render` to update their part state.\n *\n * For directives that require setting their part value asynchronously, they\n * should extend `AsyncDirective` and call `this.setValue()`.\n *\n * @param part Part to set\n * @param value Value to set\n * @param index For `AttributePart`s, the index to set\n * @param directiveParent Used internally; should not be set by user\n */\nexport const setChildPartValue = <T extends ChildPart>(\n part: T,\n value: unknown,\n directiveParent: DirectiveParent = part\n): T => {\n part._$setValue(value, directiveParent);\n return part;\n};\n\n// A sentinal value that can never appear as a part value except when set by\n// live(). Used to force a dirty-check to fail and cause a re-render.\nconst RESET_VALUE = {};\n\n/**\n * Sets the committed value of a ChildPart directly without triggering the\n * commit stage of the part.\n *\n * This is useful in cases where a directive needs to update the part such\n * that the next update detects a value change or not. When value is omitted,\n * the next update will be guaranteed to be detected as a change.\n *\n * @param part\n * @param value\n */\nexport const setCommittedValue = (part: Part, value: unknown = RESET_VALUE) =>\n (part._$committedValue = value);\n\n/**\n * Returns the committed value of a ChildPart.\n *\n * The committed value is used for change detection and efficient updates of\n * the part. It can differ from the value set by the template or directive in\n * cases where the template value is transformed before being commited.\n *\n * - `TemplateResult`s are committed as a `TemplateInstance`\n * - Iterables are committed as `Array<ChildPart>`\n * - All other types are committed as the template value or value returned or\n * set by a directive.\n *\n * @param part\n */\nexport const getCommittedValue = (part: ChildPart) => part._$committedValue;\n\n/**\n * Removes a ChildPart from the DOM, including any of its content.\n *\n * @param part The Part to remove\n */\nexport const removePart = (part: ChildPart) => {\n part._$notifyConnectionChanged?.(false, true);\n let start: ChildNode | null = part._$startNode;\n const end: ChildNode | null = wrap(part._$endNode!).nextSibling;\n while (start !== end) {\n const n: ChildNode | null = wrap(start!).nextSibling;\n (wrap(start!) as ChildNode).remove();\n start = n;\n }\n};\n\nexport const clearPart = (part: ChildPart) => {\n part._$clear();\n};\n"],"names":["_ChildPart","ChildPart","_$LH","isPrimitive","value","TemplateResultType","HTML","SVG","isTemplateResult","type","undefined","isDirectiveResult","getDirectiveClass","isSingleExpression","part","strings","createMarker","document","createComment","insertPart","containerPart","refPart","container","_$startNode","parentNode","refNode","_$endNode","startNode","insertBefore","endNode","options","nextSibling","oldParent","_$parent","parentChanged","newConnectionState","_$reparentDisconnectables","_$notifyConnectionChanged","_$isConnected","start","n","setChildPartValue","directiveParent","_$setValue","RESET_VALUE","setCommittedValue","_$committedValue","getCommittedValue","removePart","end","remove","clearPart","_$clear"],"mappings":";;;;;GAeA,MAAOA,EAAYC,GAAaC,EAkBnBC,EAAeC,GAChB,OAAVA,GAAmC,iBAATA,GAAqC,mBAATA,EAE3CC,EAAqB,CAChCC,KAAM,EACNC,IAAK,GASMC,EAAmB,CAC9BJ,EACAK,aAEA,YAASC,IAATD,OAEkDC,eAA7CN,wBAAuC,uBACvCA,wBAAuC,cAAMK,GAKvCE,EAAqBP,UAEhC,YAAoDM,eAAnDN,wBAA6C,kBAKnCQ,EAAqBR,UAEhC,iBAACA,wBAA6C,iBAUnCS,EAAsBC,QACOJ,IAAvCI,EAA2BC,QAExBC,EAAe,IAAMC,SAASC,cAAc,IAcrCC,EAAa,CACxBC,EACAC,EACAP,WAEA,MAAMQ,EAAiBF,EAAcG,KAAaC,WAE5CC,OACQf,IAAZW,EAAwBD,EAAcM,KAAYL,EAAQE,KAE5D,QAAab,IAATI,EAAoB,CACtB,MAAMa,EAAiBL,EAAWM,aAAaZ,IAAgBS,GACzDI,EAAeP,EAAWM,aAAaZ,IAAgBS,GAC7DX,EAAO,IAAIb,EACT0B,EACAE,EACAT,EACAA,EAAcU,aAEX,CACL,MAAMD,EAAef,EAAKY,KAAYK,YAChCC,EAAYlB,EAAKmB,KACjBC,EAAgBF,IAAcZ,EACpC,GAAIc,EAAe,CAUjB,IAAIC,YATJrB,EAAKsB,0BAALtB,EAAiCM,GAKjCN,EAAKmB,KAAWb,OAMqBV,IAAnCI,EAAKuB,OACJF,EAAqBf,EAAckB,QAClCN,EAAWM,MAEbxB,EAAKuB,KAA0BF,GAGnC,GAAIN,IAAYJ,GAAWS,EAAe,CACxC,IAAIK,EAAqBzB,EAAKS,KAC9B,KAAOgB,IAAUV,GAAS,CACxB,MAAMW,EAAsBD,EAAQR,YAC/BT,EAAWM,aAAaW,EAAQd,GACrCc,EAAQC,IAKd,OAAO1B,GAmBI2B,EAAoB,CAC/B3B,EACAV,EACAsC,EAAmC5B,KAEnCA,EAAK6B,KAAWvC,EAAOsC,GAChB5B,GAKH8B,EAAc,GAaPC,EAAoB,CAAC/B,EAAYV,EAAiBwC,IAC5D9B,EAAKgC,KAAmB1C,EAgBd2C,EAAqBjC,GAAoBA,EAAKgC,KAO9CE,EAAclC,oBACzBA,EAAKuB,0BAALvB,GAAiC,GAAO,GACxC,IAAIyB,EAA0BzB,EAAKS,KACnC,MAAM0B,EAA6BnC,EAAKY,KAAYK,YACpD,KAAOQ,IAAUU,GAAK,CACpB,MAAMT,EAA2BD,EAAQR,YACnCQ,EAAsBW,SAC5BX,EAAQC,IAICW,EAAarC,IACxBA,EAAKsC"}
\No newline at end of file