@lit-labs/ssr
Advanced tools
Comparing version 2.2.3 to 2.3.0
@@ -9,2 +9,6 @@ /// <reference lib="dom" /> | ||
export declare const getElementRenderer: ({ elementRenderers }: RenderInfo, tagName: string, ceClass?: typeof HTMLElement | undefined, attributes?: AttributesMap) => ElementRenderer; | ||
export interface ShadowRootOptions { | ||
mode: 'open' | 'closed'; | ||
delegatesFocus?: boolean; | ||
} | ||
/** | ||
@@ -56,2 +60,7 @@ * An object that renders elements of a certain type. | ||
/** | ||
* Override this getter to configure the element's shadow root, if one is | ||
* created with `renderShadow`. | ||
*/ | ||
get shadowRootOptions(): ShadowRootOptions; | ||
/** | ||
* Render a single element's ShadowRoot children. | ||
@@ -58,0 +67,0 @@ */ |
@@ -76,2 +76,9 @@ /// <reference lib="dom" /> | ||
/** | ||
* Override this getter to configure the element's shadow root, if one is | ||
* created with `renderShadow`. | ||
*/ | ||
get shadowRootOptions() { | ||
return { mode: 'open' }; | ||
} | ||
/** | ||
* Render an element's attributes. | ||
@@ -78,0 +85,0 @@ * |
@@ -19,2 +19,3 @@ /** | ||
constructor(tagName: string); | ||
get shadowRootOptions(): ShadowRootInit; | ||
connectedCallback(): void; | ||
@@ -21,0 +22,0 @@ attributeChangedCallback(name: string, _old: string | null, value: string | null): void; |
@@ -23,2 +23,6 @@ /** | ||
} | ||
get shadowRootOptions() { | ||
return (this.element.constructor.shadowRootOptions ?? | ||
super.shadowRootOptions); | ||
} | ||
connectedCallback() { | ||
@@ -25,0 +29,0 @@ // Call LitElement's `willUpdate` method. |
@@ -10,3 +10,3 @@ /** | ||
import * as vm from 'vm'; | ||
import resolveAsync from 'resolve'; | ||
import enhancedResolve from 'enhanced-resolve'; | ||
import { builtinModules } from 'module'; | ||
@@ -199,13 +199,7 @@ const builtIns = new Set(builtinModules); | ||
} | ||
const modulePath = await resolve(specifier, { | ||
basedir: path.dirname(referrerPath), | ||
moduleDirectory: ['node_modules'], | ||
const modulePath = await resolve(specifier, path.dirname(referrerPath), { | ||
modules: ['node_modules'], | ||
extensions: ['.js'], | ||
// Some packages use a non-standard alternative to the "main" field | ||
// in their package.json to differentiate their ES module version. | ||
packageFilter: (packageJson) => { | ||
packageJson.main = | ||
packageJson.module ?? packageJson['jsnext:main'] ?? packageJson.main; | ||
return packageJson; | ||
}, | ||
mainFields: ['module', 'jsnext:main', 'main'], | ||
conditionNames: ['node', 'import'], | ||
}); | ||
@@ -221,5 +215,6 @@ return pathToFileURL(modulePath); | ||
}; | ||
const resolve = async (id, opts) => { | ||
const resolve = async (id, path, opts) => { | ||
const resolver = enhancedResolve.create(opts); | ||
return new Promise((res, rej) => { | ||
resolveAsync(id, opts, (err, resolved) => { | ||
resolver({}, path, id, {}, (err, resolved) => { | ||
if (err != null) { | ||
@@ -226,0 +221,0 @@ rej(err); |
/// <reference lib="dom" /> | ||
import { ElementRenderer, ElementRendererConstructor } from './element-renderer.js'; | ||
declare module 'parse5' { | ||
declare module 'parse5/dist/tree-adapters/default.js' { | ||
interface Element { | ||
@@ -5,0 +5,0 @@ isDefinedCustomElement?: boolean; |
@@ -10,3 +10,4 @@ /// <reference lib="dom" /> | ||
import { escapeHtml } from './util/escape-html.js'; | ||
import { traverse, parseFragment, isCommentNode, isElement, } from './util/parse5-utils.js'; | ||
import { parseFragment } from 'parse5'; | ||
import { isElementNode, isCommentNode, traverse } from '@parse5/tools'; | ||
import { isRenderLightDirective } from '@lit-labs/ssr-client/directives/render-light.js'; | ||
@@ -182,3 +183,3 @@ import { reflectedAttributeName } from './reflected-attributes.js'; | ||
traverse(ast, { | ||
pre(node, parent) { | ||
'pre:node'(node, parent) { | ||
if (isCommentNode(node)) { | ||
@@ -191,3 +192,3 @@ if (node.data === markerMatch) { | ||
index: nodeIndex, | ||
useCustomElementInstance: parent && isElement(parent) && parent.isDefinedCustomElement, | ||
useCustomElementInstance: parent && isElementNode(parent) && parent.isDefinedCustomElement, | ||
}); | ||
@@ -197,3 +198,3 @@ } | ||
} | ||
else if (isElement(node)) { | ||
else if (isElementNode(node)) { | ||
// Whether to flush the start tag. This is necessary if we're changing | ||
@@ -308,4 +309,4 @@ // any of the attributes in the tag, so it's true for custom-elements | ||
}, | ||
post(node) { | ||
if (isElement(node) && node.isDefinedCustomElement) { | ||
node(node) { | ||
if (isElementNode(node) && node.isDefinedCustomElement) { | ||
ops.push({ | ||
@@ -505,3 +506,9 @@ type: 'custom-element-close', | ||
if (shadowContents !== undefined) { | ||
yield '<template shadowroot="open">'; | ||
const { mode = 'open', delegatesFocus } = instance.shadowRootOptions ?? {}; | ||
// `delegatesFocus` is intentionally allowed to coerce to boolean to | ||
// match web platform behavior. | ||
const delegatesfocusAttr = delegatesFocus | ||
? ' shadowrootdelegatesfocus' | ||
: ''; | ||
yield `<template shadowroot="${mode}"${delegatesfocusAttr}>`; | ||
yield* shadowContents; | ||
@@ -508,0 +515,0 @@ yield '</template>'; |
@@ -6,43 +6,4 @@ /** | ||
*/ | ||
/** | ||
* TODO(usergenic): The following set of helper functions are more-or-less | ||
* copied from the npm package dom5 which could not be brought in at this | ||
* time because it is bound to `parse5@4` where this package uses `parse5@5`. | ||
* Once dom5 is updated, we can just use that package and not maintain these | ||
* here. | ||
*/ | ||
import { Node, Element, CommentNode, DocumentFragment, ParentNode } from 'parse5'; | ||
import * as parse5lib from 'parse5'; | ||
export declare const parseFragment: typeof parse5lib.parseFragment; | ||
export declare function filter(iter: any, predicate: any, matches?: any[]): any[]; | ||
export declare function getAttr(ast: Node, name: string): any; | ||
export declare function getTextContent(node: any): string; | ||
export declare function setAttr(ast: any, name: any, value: any): void; | ||
export declare function insertBefore(parent: any, oldNode: any, newNode: any): void; | ||
export declare function insertNode(parent: any, index: any, newNode: any, replace?: any): void; | ||
export declare function isElement(node: Node): node is Element; | ||
export declare function isCommentNode(node: Node): node is CommentNode; | ||
export declare function isDocumentFragment(node: Node): node is DocumentFragment; | ||
export declare function isTextNode(node: Node): node is parse5lib.TextNode; | ||
export declare type GetChildNodes = (node: ParentNode) => Array<Node> | undefined; | ||
export declare const defaultChildNodes: GetChildNodes; | ||
export declare function depthFirst(node: Node | DocumentFragment, getChildNodes?: GetChildNodes): Iterable<Node>; | ||
export declare function nodeWalkAll(node: any, predicate: any, matches?: any, getChildNodes?: any): any[]; | ||
export declare function removeFakeRootElements(node: any): void; | ||
export declare function removeNode(node: any): void; | ||
export declare function removeNodeSaveChildren(node: any): void; | ||
export declare function setTextContent(node: any, value: any): void; | ||
export declare function newTextNode(value: any): { | ||
nodeName: string; | ||
value: any; | ||
parentNode: undefined; | ||
attrs: never[]; | ||
__location: undefined; | ||
}; | ||
export interface Visitor { | ||
pre?: (node: Node, parent?: ParentNode) => boolean | void; | ||
post?: (node: Node, parent?: ParentNode) => boolean | void; | ||
getChildNodes?: GetChildNodes; | ||
} | ||
export declare const traverse: (node: Node, visitor: Visitor, parent?: ParentNode) => void; | ||
import { Node } from 'parse5/dist/tree-adapters/default.js'; | ||
export declare function removeFakeRootElements(node: Node): void; | ||
//# sourceMappingURL=parse5-utils.d.ts.map |
@@ -6,106 +6,9 @@ /** | ||
*/ | ||
import { createRequire } from 'module'; | ||
const require = createRequire(import.meta.url); | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const parse5 = require('parse5'); | ||
export const parseFragment = parse5.parseFragment; | ||
export function filter(iter, predicate, matches = []) { | ||
for (const value of iter) { | ||
if (predicate(value)) { | ||
matches.push(value); | ||
} | ||
} | ||
return matches; | ||
} | ||
export function getAttr(ast, name) { | ||
if (ast.hasOwnProperty('attrs')) { | ||
const attr = ast.attrs.find(({ name: attrName }) => attrName === name); | ||
if (attr) { | ||
return attr.value; | ||
} | ||
} | ||
} | ||
export function getTextContent(node) { | ||
if (isCommentNode(node)) { | ||
return node.data || ''; | ||
} | ||
if (isTextNode(node)) { | ||
return node.value || ''; | ||
} | ||
const subtree = nodeWalkAll(node, isTextNode); | ||
return subtree.map(getTextContent).join(''); | ||
} | ||
export function setAttr(ast, name, value) { | ||
const attr = ast.attrs.find(({ name: attrName }) => attrName === name); | ||
if (attr) { | ||
attr.value = value; | ||
} | ||
else { | ||
ast.attrs.push({ name, value }); | ||
} | ||
} | ||
export function insertBefore(parent, oldNode, newNode) { | ||
const index = parent.childNodes.indexOf(oldNode); | ||
insertNode(parent, index, newNode); | ||
} | ||
export function insertNode(parent, index, newNode, replace = undefined) { | ||
if (!parent.childNodes) { | ||
parent.childNodes = []; | ||
} | ||
let newNodes = []; | ||
let removedNode = replace ? parent.childNodes[index] : null; | ||
if (newNode) { | ||
if (isDocumentFragment(newNode)) { | ||
if (newNode.childNodes) { | ||
newNodes = Array.from(newNode.childNodes); | ||
newNode.childNodes.length = 0; | ||
} | ||
} | ||
else { | ||
newNodes = [newNode]; | ||
removeNode(newNode); | ||
} | ||
} | ||
if (replace) { | ||
removedNode = parent.childNodes[index]; | ||
} | ||
Array.prototype.splice.apply(parent.childNodes, [index, replace ? 1 : 0].concat(newNodes)); | ||
newNodes.forEach((n) => { | ||
n.parentNode = parent; | ||
}); | ||
if (removedNode) { | ||
removedNode.parentNode = undefined; | ||
} | ||
} | ||
export function isElement(node) { | ||
return node.tagName !== undefined; | ||
} | ||
export function isCommentNode(node) { | ||
return node.nodeName === '#comment'; | ||
} | ||
export function isDocumentFragment(node) { | ||
return node.nodeName === '#document-fragment'; | ||
} | ||
export function isTextNode(node) { | ||
return node.nodeName === '#text'; | ||
} | ||
export const defaultChildNodes = (node) => node.childNodes; | ||
export function* depthFirst(node, getChildNodes = defaultChildNodes) { | ||
yield node; | ||
const childNodes = getChildNodes(node); | ||
if (childNodes === undefined) { | ||
return; | ||
} | ||
for (const child of childNodes) { | ||
yield* depthFirst(child, getChildNodes); | ||
} | ||
} | ||
export function nodeWalkAll(node, predicate, matches = [], getChildNodes = defaultChildNodes) { | ||
return filter(depthFirst(node, getChildNodes), predicate, matches); | ||
} | ||
import { traverse, replaceWith, isElementNode } from '@parse5/tools'; | ||
export function removeFakeRootElements(node) { | ||
const fakeRootElements = []; | ||
traverse(node, { | ||
pre: (node) => { | ||
if (node.nodeName && | ||
'pre:node': (node) => { | ||
if (isElementNode(node) && | ||
node.nodeName && | ||
node.nodeName.match(/^(html|head|body)$/i) && | ||
@@ -117,65 +20,6 @@ !node.sourceCodeLocation) { | ||
}); | ||
fakeRootElements.forEach(removeNodeSaveChildren); | ||
} | ||
export function removeNode(node) { | ||
const parent = node.parentNode; | ||
if (parent && parent.childNodes) { | ||
const idx = parent.childNodes.indexOf(node); | ||
parent.childNodes.splice(idx, 1); | ||
for (const el of fakeRootElements) { | ||
replaceWith(el, ...el.childNodes); | ||
} | ||
node.parentNode = undefined; | ||
} | ||
export function removeNodeSaveChildren(node) { | ||
// We can't save the children if there's no parent node to provide | ||
// for them. | ||
const fosterParent = node.parentNode; | ||
if (!fosterParent) { | ||
return; | ||
} | ||
const children = (node.childNodes || []).slice(); | ||
for (const child of children) { | ||
insertBefore(node.parentNode, node, child); | ||
} | ||
removeNode(node); | ||
} | ||
export function setTextContent(node, value) { | ||
if (isCommentNode(node)) { | ||
node.data = value; | ||
} | ||
else if (isTextNode(node)) { | ||
node.value = value; | ||
} | ||
else { | ||
const tn = newTextNode(value); | ||
tn.parentNode = node; | ||
node.childNodes = [tn]; | ||
} | ||
} | ||
export function newTextNode(value) { | ||
return { | ||
nodeName: '#text', | ||
value: value, | ||
parentNode: undefined, | ||
attrs: [], | ||
__location: undefined, | ||
}; | ||
} | ||
export const traverse = (node, visitor, parent) => { | ||
const getChildNodes = visitor.getChildNodes ?? defaultChildNodes; | ||
let visitChildren = true; | ||
if (typeof visitor.pre === 'function') { | ||
visitChildren = visitor.pre(node, parent); | ||
} | ||
if (visitChildren !== false) { | ||
const childNodes = getChildNodes(node); | ||
if (childNodes !== undefined) { | ||
for (const child of childNodes) { | ||
traverse(child, visitor, node); | ||
} | ||
} | ||
} | ||
if (typeof visitor.post === 'function') { | ||
visitor.post(node, parent); | ||
} | ||
}; | ||
//# sourceMappingURL=parse5-utils.js.map |
{ | ||
"name": "@lit-labs/ssr", | ||
"type": "module", | ||
"version": "2.2.3", | ||
"version": "2.3.0", | ||
"publishConfig": { | ||
@@ -137,5 +137,5 @@ "access": "public" | ||
"@types/koa": "^2.0.49", | ||
"@types/koa__router": "^8.0.2", | ||
"@types/koa-cors": "*", | ||
"@types/koa-static": "^4.0.1", | ||
"@types/koa__router": "^8.0.2", | ||
"@types/parse5": "^6.0.1", | ||
@@ -153,10 +153,11 @@ "@types/resolve": "^1.20.2", | ||
"@lit-labs/ssr-client": "^1.0.0", | ||
"@lit/reactive-element": "^1.4.0", | ||
"@lit/reactive-element": "^1.5.0", | ||
"@parse5/tools": "^0.1.0", | ||
"@types/node": "^16.0.0", | ||
"lit": "^2.3.0", | ||
"enhanced-resolve": "^5.10.0", | ||
"lit": "^2.5.0", | ||
"lit-element": "^3.1.0", | ||
"lit-html": "^2.3.0", | ||
"lit-html": "^2.5.0", | ||
"node-fetch": "^3.2.8", | ||
"parse5": "^6.0.1", | ||
"resolve": "^1.10.1" | ||
"parse5": "^7.1.1" | ||
}, | ||
@@ -163,0 +164,0 @@ "engines": { |
@@ -101,10 +101,8 @@ # @lit-labs/ssr | ||
<html> | ||
<head> | ||
</head> | ||
<head> </head> | ||
<body> | ||
<app-shell> | ||
<app-page-one></app-page-one> | ||
<app-page-two></app-page-two> | ||
</app-component> | ||
</app-shell> | ||
@@ -116,3 +114,3 @@ <script type="module"> | ||
hasNativeDeclarativeShadowRoots, | ||
hydrateShadowRoots | ||
hydrateShadowRoots, | ||
} from './node_modules/@webcomponents/template-shadowroot/template-shadowroot.js'; | ||
@@ -126,3 +124,2 @@ if (!hasNativeDeclarativeShadowRoots()) { | ||
</script> | ||
</body> | ||
@@ -129,0 +126,0 @@ </html> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4
191322
10
1768
148
+ Added@parse5/tools@^0.1.0
+ Addedenhanced-resolve@^5.10.0
+ Added@parse5/tools@0.1.0(transitive)
+ Addedenhanced-resolve@5.17.1(transitive)
+ Addedentities@4.5.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedparse5@7.2.0(transitive)
+ Addedtapable@2.2.1(transitive)
- Removedresolve@^1.10.1
- Removedfunction-bind@1.1.2(transitive)
- Removedhasown@2.0.2(transitive)
- Removedis-core-module@2.15.1(transitive)
- Removedparse5@6.0.1(transitive)
- Removedpath-parse@1.0.7(transitive)
- Removedresolve@1.22.8(transitive)
- Removedsupports-preserve-symlinks-flag@1.0.0(transitive)
Updated@lit/reactive-element@^1.5.0
Updatedlit@^2.5.0
Updatedlit-html@^2.5.0
Updatedparse5@^7.1.1