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 | 26x 26x 26x 1572x 1572x 1019x 1019x 30x 989x 4x 26x 35x 35x 19x 16x 16x 26x 8x 7x 7x 3x 3x 4x | import {HtmlCompilerModule, HtmlCompilerContext} from '../htmlCompiler';
import {StyleNode, TagNode} from '../../..';
/**
* Node tag that indicates that a node has already been processed by DeduplicateModule.
* Nodes with this tag set will be skipped.
*/
export const NODE_TAG_IS_DEDUPLICATED = 'DeduplicateModule.IsDeduplicated';
/**
* Removes unnecessary duplicate nodes from the DOM.
*/
export class DeduplicateModule implements HtmlCompilerModule {
enterNode(htmlContext: HtmlCompilerContext): void {
const node = htmlContext.node;
// Don't process nodes more than once.
// This can happen if a style or link node is generated inside a nested fragment.
if (!node.nodeTags.has(NODE_TAG_IS_DEDUPLICATED)) {
// mark as processed
node.nodeTags.add(NODE_TAG_IS_DEDUPLICATED);
if (StyleNode.isStyleNode(node)) {
dedupeStyle(node, htmlContext);
} else if (TagNode.isTagNode(node) && node.tagName === 'link') {
dedupeLink(node, htmlContext);
}
}
}
}
/**
* Removes or remembers a style tag.
* If the contents of the style are unique, then it is preserved and the contents are remembered.
* If the contents are not unique, then the node is removed.
*
* TODO keep duplicates if they have different MIME types
*
* @param styleNode Style node to process
* @param htmlContext current context
*/
export function dedupeStyle(styleNode: StyleNode, htmlContext: HtmlCompilerContext): void {
// get the style text from the node.
// at this point in compilation the only style nodes should be raw (uncompiled) so there should only be 0 or 1 child node
const styleTextNode = styleNode.firstChildText;
// check if it contains unique styles
if (styleTextNode?.hasContent && !htmlContext.pipelineContext.stylesInPage.has(styleTextNode.textContent)) {
// this style is unique, so save it
htmlContext.pipelineContext.stylesInPage.add(styleTextNode.textContent);
} else {
// if not unique, then cull;
styleNode.removeSelf();
htmlContext.setDeleted();
}
}
/**
* Removes or remembers a link tag.
* If the href of the link is unique, then it is preserved and the href are remembered.
* If the href is not unique, then the node is removed.
*
* @param linkNode link tag to process
* @param htmlContext current context
*/
export function dedupeLink(linkNode: TagNode, htmlContext: HtmlCompilerContext): void {
// ignore links that don't go anywhere
if (linkNode.hasValueAttribute('href')) {
const href = linkNode.getRequiredValueAttribute('href');
// check if we have seen this link before
if (htmlContext.pipelineContext.linksInPage.has(href)) {
// duplicate, so cull it
linkNode.removeSelf();
htmlContext.setDeleted();
} else {
// unique link, so save it
htmlContext.pipelineContext.linksInPage.add(href);
}
}
} |