Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 26x 26x 26x 26x 1525x 44x 26x 44x 44x 44x 44x 44x 44x 44x 44x 26x 47x 47x 87x 87x 87x 87x 47x 26x 87x 87x 25x 25x 87x 26x 89x 11x 78x 26x 89x 11x 78x 26x 48x 30x 30x 30x 30x | import {HtmlCompilerModule, HtmlCompilerContext} from '../htmlCompiler'; import { MFragmentNode, DocumentNode, FragmentContext, Node, MContentNode, ScopeData, SlotReferenceNode } from '../../..'; import {resolveResPath} from '../../../fs/pathUtils'; import {convertSnakeCaseToCamelCase} from '../../../util/caseUtils'; /** * Resolve <m-fragment> and replace with compiled HTML */ export class FragmentModule implements HtmlCompilerModule { async exitNode(htmlContext: HtmlCompilerContext): Promise<void> { if (MFragmentNode.isMFragmentNode(htmlContext.node) ) { await replaceFragment(htmlContext.node, htmlContext); } } } export async function replaceFragment(mFragment: MFragmentNode, htmlContext: HtmlCompilerContext): Promise<void> { const pipelineContext = htmlContext.pipelineContext; // get slot contents const slotContents: Map<string, DocumentNode> = extractSlotContents(mFragment); // create usage context const parentFragmentContext = pipelineContext.fragmentContext; const fragmentContext: FragmentContext = { slotContents: slotContents, scope: createFragmentScope(mFragment), fragmentResPath: mFragment.src, rootResPath: parentFragmentContext.rootResPath }; // compute path to fragment const fragmentPath = resolveResPath(mFragment.src, pipelineContext.fragment.path); // call pipeline to load reference const fragment = await pipelineContext.pipeline.compileFragment(fragmentPath, fragmentContext); // replace with compiled fragment mFragment.replaceSelf(fragment.dom.childNodes); htmlContext.setDeleted(); } export function extractSlotContents(mFragment: MFragmentNode): Map<string, DocumentNode> { const slotMap = new Map<string, DocumentNode>(); // loop through all direct children of fragment reference for (const node of Array.from(mFragment.childNodes)) { // get content for this slot const slotContents: Node[] = convertNodeToContent(node); // check if it specified a slot const slotName: string = getContentTargetName(node); // get dom for this slot const slotDom: DocumentNode = getContentDom(slotMap, slotName); // add slot contents to new DOM (will automatically detach them) slotDom.appendChildren(slotContents); } return slotMap; } export function getContentDom(slotMap: Map<string, DocumentNode>, slotName: string): DocumentNode { let slotDom: DocumentNode | undefined = slotMap.get(slotName); if (slotDom === undefined) { slotDom = new DocumentNode(); slotMap.set(slotName, slotDom); } return slotDom; } export function convertNodeToContent(node: Node): Node[] { // check if this element is an m-content if (MContentNode.isMContentNode(node)) { return node.childNodes; } else { return [ node ]; } } export function getContentTargetName(node: Node): string { if (MContentNode.isMContentNode(node)) { return node.slot; } else { return SlotReferenceNode.DefaultSlotName; } } export function createFragmentScope(fragmentNode: MFragmentNode): ScopeData { return fragmentNode.parameters // get parameter names .map(param => param[0]) // convert parameter / attribute names to scope names .map(parameterName => convertSnakeCaseToCamelCase(parameterName)) // copy all data from MFragmentNode scope to new fragment scope .reduce<ScopeData>((fragmentScope, scopeName) => { // copy current parameter from scope prototype chain into an isolated ScopeData fragmentScope[scopeName] = fragmentNode.nodeData[scopeName]; return fragmentScope; }, {}); } |