Skip to content

Infrastructure for building unversioned pages from the stable version. #1107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ packages/lit-dev-content/site/fonts/manrope
packages/lit-dev-content/temp
packages/lit-dev-content/samples/js
packages/lit-dev-content/src/public-vars.ts
# The unversioned docs are generated by:
#
# `npm run build:unversioned-docs -w lit-dev-content`
packages/lit-dev-content/site/docs/unversioned

packages/lit-dev-api/api-data/*/repo/
packages/lit-dev-api/api-data/*/INSTALLED
Expand Down
30 changes: 15 additions & 15 deletions packages/lit-dev-api/api-data/lit-2/pages.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"name": "LitElement",
"comment": {
"shortText": "Base element class that manages element properties and attributes, and\nrenders a lit-html template.",
"text": "To define a component, subclass `LitElement` and implement a\n`render` method to provide the component's template. Define properties\nusing the [`properties`](/docs/api/LitElement/#LitElement.properties) property or the\n[`property`](/docs/api/decorators/#property) decorator.\n"
"text": "To define a component, subclass `LitElement` and implement a\n`render` method to provide the component's template. Define properties\nusing the [`properties`](/docs/v2/api/LitElement/#LitElement.properties) property or the\n[`property`](/docs/v2/api/decorators/#property) decorator.\n"
},
"sources": [
{
Expand Down Expand Up @@ -949,7 +949,7 @@
"tag": "@nocollapse"
}
],
"shortText": "Creates a property accessor on the element prototype if one does not exist\nand stores a [`PropertyDeclaration`](/docs/api/ReactiveElement/#PropertyDeclaration) for the property with the\ngiven options. The property setter calls the property's `hasChanged`\nproperty option or uses a strict identity check to determine whether or not\nto request an update.",
"shortText": "Creates a property accessor on the element prototype if one does not exist\nand stores a [`PropertyDeclaration`](/docs/v2/api/ReactiveElement/#PropertyDeclaration) for the property with the\ngiven options. The property setter calls the property's `hasChanged`\nproperty option or uses a strict identity check to determine whether or not\nto request an update.",
"text": "This method may be overridden to customize properties; however,\nwhen doing so, it's important to call `super.createProperty` to ensure\nthe property is setup correctly. This method calls\n`getPropertyDescriptor` internally to get a descriptor to install.\nTo customize what properties do when they are get or set, override\n`getPropertyDescriptor`. To customize the options for a property,\nimplement `createProperty` like this:\n```ts\nstatic createProperty(name, options) {\n options = Object.assign(options, {myOption: true});\n super.createProperty(name, options);\n}\n```\n"
},
"sources": [
Expand Down Expand Up @@ -1222,7 +1222,7 @@
}
],
"shortText": "Returns the property options associated with the given property.\nThese options are defined with a `PropertyDeclaration` via the `properties`\nobject or the `@property` decorator and are registered in\n`createProperty(...)`.",
"text": "Note, this method should be considered \"final\" and not overridden. To\ncustomize the options for a given property, override\n[`createProperty`](/docs/api/LitElement/#LitElement.createProperty).\n"
"text": "Note, this method should be considered \"final\" and not overridden. To\ncustomize the options for a given property, override\n[`createProperty`](/docs/v2/api/LitElement/#LitElement.createProperty).\n"
},
"sources": [
{
Expand Down Expand Up @@ -1760,7 +1760,7 @@
"tag": "@nocollapse"
}
],
"shortText": "Array of styles to apply to the element. The styles should be defined\nusing the [`css`](/docs/api/styles/#css) tag function, via constructible stylesheets, or\nimported from native CSS module scripts.",
"shortText": "Array of styles to apply to the element. The styles should be defined\nusing the [`css`](/docs/v2/api/styles/#css) tag function, via constructible stylesheets, or\nimported from native CSS module scripts.",
"text": "Note on Content Security Policy:\nElement styles are implemented with `<style>` tags when the browser doesn't\nsupport adopted StyleSheets. To use such `<style>` tags with the style-src\nCSP directive, the style-src value must either include 'unsafe-inline' or\n`nonce-<base64-value>` with `<base64-value>` replaced be a server-generated\nnonce.\nTo provide a nonce to use on generated `<style>` elements, set\n`window.litNonce` to a server-generated nonce in your page's HTML, before\nloading application code:\n```html\n<script>\n // Generated and unique per request:\n window.litNonce = 'a1b2c3d4';\n</script>\n```\n"
},
"sources": [
Expand Down Expand Up @@ -3974,7 +3974,7 @@
"tag": "@nocollapse"
}
],
"shortText": "Creates a property accessor on the element prototype if one does not exist\nand stores a [`PropertyDeclaration`](/docs/api/ReactiveElement/#PropertyDeclaration) for the property with the\ngiven options. The property setter calls the property's `hasChanged`\nproperty option or uses a strict identity check to determine whether or not\nto request an update.",
"shortText": "Creates a property accessor on the element prototype if one does not exist\nand stores a [`PropertyDeclaration`](/docs/v2/api/ReactiveElement/#PropertyDeclaration) for the property with the\ngiven options. The property setter calls the property's `hasChanged`\nproperty option or uses a strict identity check to determine whether or not\nto request an update.",
"text": "This method may be overridden to customize properties; however,\nwhen doing so, it's important to call `super.createProperty` to ensure\nthe property is setup correctly. This method calls\n`getPropertyDescriptor` internally to get a descriptor to install.\nTo customize what properties do when they are get or set, override\n`getPropertyDescriptor`. To customize the options for a property,\nimplement `createProperty` like this:\n```ts\nstatic createProperty(name, options) {\n options = Object.assign(options, {myOption: true});\n super.createProperty(name, options);\n}\n```\n"
},
"sources": [
Expand Down Expand Up @@ -4215,7 +4215,7 @@
}
],
"shortText": "Returns the property options associated with the given property.\nThese options are defined with a `PropertyDeclaration` via the `properties`\nobject or the `@property` decorator and are registered in\n`createProperty(...)`.",
"text": "Note, this method should be considered \"final\" and not overridden. To\ncustomize the options for a given property, override\n[`createProperty`](/docs/api/ReactiveElement/#ReactiveElement.createProperty).\n"
"text": "Note, this method should be considered \"final\" and not overridden. To\ncustomize the options for a given property, override\n[`createProperty`](/docs/v2/api/ReactiveElement/#ReactiveElement.createProperty).\n"
},
"sources": [
{
Expand Down Expand Up @@ -4620,7 +4620,7 @@
"tag": "@nocollapse"
}
],
"shortText": "Array of styles to apply to the element. The styles should be defined\nusing the [`css`](/docs/api/styles/#css) tag function, via constructible stylesheets, or\nimported from native CSS module scripts.",
"shortText": "Array of styles to apply to the element. The styles should be defined\nusing the [`css`](/docs/v2/api/styles/#css) tag function, via constructible stylesheets, or\nimported from native CSS module scripts.",
"text": "Note on Content Security Policy:\nElement styles are implemented with `<style>` tags when the browser doesn't\nsupport adopted StyleSheets. To use such `<style>` tags with the style-src\nCSP directive, the style-src value must either include 'unsafe-inline' or\n`nonce-<base64-value>` with `<base64-value>` replaced be a server-generated\nnonce.\nTo provide a nonce to use on generated `<style>` elements, set\n`window.litNonce` to a server-generated nonce in your page's HTML, before\nloading application code:\n```html\n<script>\n // Generated and unique per request:\n window.litNonce = 'a1b2c3d4';\n</script>\n```\n"
},
"sources": [
Expand Down Expand Up @@ -6963,7 +6963,7 @@
"name": "css",
"comment": {
"shortText": "A template literal tag which can be used with LitElement's\n`styles` property to set element styles.",
"text": "For security reasons, only literal string values and number may be used in\nembedded expressions. To incorporate non-literal values [`unsafeCSS`](/docs/api/styles/#unsafeCSS)\nmay be used inside an expression.\n"
"text": "For security reasons, only literal string values and number may be used in\nembedded expressions. To incorporate non-literal values [`unsafeCSS`](/docs/v2/api/styles/#unsafeCSS)\nmay be used inside an expression.\n"
},
"sources": [
{
Expand Down Expand Up @@ -7295,7 +7295,7 @@
{
"name": "unsafeCSS",
"comment": {
"shortText": "Wrap a value for interpolation in a [`css`](/docs/api/styles/#css) tagged template literal.",
"shortText": "Wrap a value for interpolation in a [`css`](/docs/v2/api/styles/#css) tagged template literal.",
"text": "This is unsafe because untrusted CSS text can be used to phone home\nor exfiltrate data to an attacker controlled site. Take care to only use\nthis with trusted input.\n"
},
"sources": [
Expand Down Expand Up @@ -7723,7 +7723,7 @@
"tag": "@ExportDecoratedItems"
}
],
"shortText": "A property decorator which creates a reactive property that reflects a\ncorresponding attribute value. When a decorated property is set\nthe element will update and render. A [`PropertyDeclaration`](/docs/api/ReactiveElement/#PropertyDeclaration) may\noptionally be supplied to configure property features.",
"shortText": "A property decorator which creates a reactive property that reflects a\ncorresponding attribute value. When a decorated property is set\nthe element will update and render. A [`PropertyDeclaration`](/docs/v2/api/ReactiveElement/#PropertyDeclaration) may\noptionally be supplied to configure property features.",
"text": "This decorator should only be used for public fields. As public fields,\nproperties should be considered as primarily settable by element users,\neither via attribute or the property itself.\nGenerally, properties that are changed by the element should be private or\nprotected fields and should use the `state` decorator.\nHowever, sometimes element code does need to set a public property. This\nshould typically only be done in response to user interaction, and an event\nshould be fired informing the user; for example, a checkbox sets its\n`checked` property when clicked and fires a `changed` event. Mutating public\nproperties should typically not be done for non-primitive (object or array)\nproperties. In other cases when an element needs to manage state, a private\nproperty decorated via the `state` decorator should be used. When\nneeded, state properties can be initialized via public properties to\nfacilitate complex interactions.\n```ts\nclass MyElement {\n @property({ type: Boolean })\n clicked = false;\n}\n```\n"
},
"sources": [
Expand Down Expand Up @@ -8082,7 +8082,7 @@
"name": "queryAssignedElements",
"comment": {
"shortText": "A property decorator that converts a class property into a getter that\nreturns the `assignedElements` of the given `slot`. Provides a declarative\nway to use\n[`HTMLSlotElement.assignedElements`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedElements).",
"text": "Can be passed an optional [`QueryAssignedElementsOptions`](/docs/api/decorators/#QueryAssignedElementsOptions) object.\nExample usage:\n```ts\nclass MyElement {\n @queryAssignedElements({ slot: 'list' })\n listItems!: Array<HTMLElement>;\n @queryAssignedElements()\n unnamedSlotEls!: Array<HTMLElement>;\n render() {\n return html`\n <slot name=\"list\"></slot>\n <slot></slot>\n `;\n }\n}\n```\nNote, the type of this property should be annotated as `Array<HTMLElement>`.\n"
"text": "Can be passed an optional [`QueryAssignedElementsOptions`](/docs/v2/api/decorators/#QueryAssignedElementsOptions) object.\nExample usage:\n```ts\nclass MyElement {\n @queryAssignedElements({ slot: 'list' })\n listItems!: Array<HTMLElement>;\n @queryAssignedElements()\n unnamedSlotEls!: Array<HTMLElement>;\n render() {\n return html`\n <slot name=\"list\"></slot>\n <slot></slot>\n `;\n }\n}\n```\nNote, the type of this property should be annotated as `Array<HTMLElement>`.\n"
},
"sources": [
{
Expand Down Expand Up @@ -8198,7 +8198,7 @@
"name": "queryAssignedNodes",
"comment": {
"shortText": "A property decorator that converts a class property into a getter that\nreturns the `assignedNodes` of the given `slot`.",
"text": "Can be passed an optional [`QueryAssignedNodesOptions`](/docs/api/decorators/#QueryAssignedNodesOptions) object.\nExample usage:\n```ts\nclass MyElement {\n @queryAssignedNodes({slot: 'list', flatten: true})\n listItems!: Array<Node>;\n render() {\n return html`\n <slot name=\"list\"></slot>\n `;\n }\n}\n```\nNote the type of this property should be annotated as `Array<Node>`.\n"
"text": "Can be passed an optional [`QueryAssignedNodesOptions`](/docs/v2/api/decorators/#QueryAssignedNodesOptions) object.\nExample usage:\n```ts\nclass MyElement {\n @queryAssignedNodes({slot: 'list', flatten: true})\n listItems!: Array<Node>;\n render() {\n return html`\n <slot name=\"list\"></slot>\n `;\n }\n}\n```\nNote the type of this property should be annotated as `Array<Node>`.\n"
},
"sources": [
{
Expand Down Expand Up @@ -8709,7 +8709,7 @@
{
"name": "QueryAssignedElementsOptions",
"comment": {
"shortText": "Options for the [`queryAssignedElements`](/docs/api/decorators/#queryAssignedElements) decorator. Extends the\noptions that can be passed into\n[HTMLSlotElement.assignedElements](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedElements)."
"shortText": "Options for the [`queryAssignedElements`](/docs/v2/api/decorators/#queryAssignedElements) decorator. Extends the\noptions that can be passed into\n[HTMLSlotElement.assignedElements](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedElements)."
},
"children": [
{
Expand Down Expand Up @@ -8830,7 +8830,7 @@
{
"name": "QueryAssignedNodesOptions",
"comment": {
"shortText": "Options for the [`queryAssignedNodes`](/docs/api/decorators/#queryAssignedNodes) decorator. Extends the options\nthat can be passed into [HTMLSlotElement.assignedNodes](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedNodes)."
"shortText": "Options for the [`queryAssignedNodes`](/docs/v2/api/decorators/#queryAssignedNodes) decorator. Extends the options\nthat can be passed into [HTMLSlotElement.assignedNodes](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedNodes)."
},
"children": [
{
Expand Down Expand Up @@ -28227,7 +28227,7 @@
{
"name": "PropertyValueMap",
"comment": {
"shortText": "Do not use, instead prefer [`PropertyValues`](/docs/api/ReactiveElement/#PropertyValues)."
"shortText": "Do not use, instead prefer [`PropertyValues`](/docs/v2/api/ReactiveElement/#PropertyValues)."
},
"children": [
{
Expand Down
66 changes: 63 additions & 3 deletions packages/lit-dev-content/.eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const DEV = ENV.eleventyMode === 'dev';

const cspInlineScriptHashes = new Set();

/**
* @param {import("@11ty/eleventy/src/UserConfig")} eleventyConfig
* @returns {ReturnType<import("@11ty/eleventy/src/defaultConfig")>}
*/
module.exports = function (eleventyConfig) {
// https://github.com/JordanShurmer/eleventy-plugin-toc#readme
eleventyConfig.addPlugin(pluginTOC, {
Expand Down Expand Up @@ -158,6 +162,48 @@ ${content}
return content.replace(/<a class="anchor".*<\/a>/g, '');
});

/**
* For the latest versioned urls, this filter returns the unversioned url
* which is used in the rel=canonical link.
*/
eleventyConfig.addFilter(
'removeLatestVersionFromUrl',
function (url, latestVersion) {
if (!latestVersion) {
throw new Error(
`No latestVersion provided to 'removeLatestVersionFromUrl`
);
}
if (!url.includes(`/${latestVersion}/`)) {
throw new Error(
`'${url}' does not include the latestVersion versioned path segment`
);
}
return url.replace(`/${latestVersion}/`, '/');
}
);

/**
* All docs/* content on lit.dev is versioned. So all cross links are
* versioned. We automatically generate unversioned docs from the latest Lit
* version. This filter fixes the cross linking such that links on unversioned
* pages link to other unversioned pages.
*/
eleventyConfig.addFilter(
'fixUnversionedCrossLinks',
function (content, isUnversionedUrl, latestVersion) {
if (!isUnversionedUrl) {
return content;
}
if (!latestVersion) {
throw new Error(
`latestVersion not provided to 'fixUnversionedCrossLinks`
);
}
return content.replaceAll(`/docs/${latestVersion}/`, '/docs/');
}
);

eleventyConfig.addFilter('removeExtension', function (url) {
const extension = path.extname(url);
return url.substring(0, url.length - extension.length);
Expand Down Expand Up @@ -194,7 +240,19 @@ ${content}

eleventyConfig.addCollection('docs-v2', function (collection) {
const docs = collection
.getFilteredByGlob(['site/docs/*', 'site/docs/!(v1)/**'])
.getFilteredByGlob(['site/docs/v2/**'])
.sort(sortDocs);
for (const page of docs) {
documentByUrl.set(page.url, page);
}
return docs;
});

// Collection that contains the built duplicate docs for the current
// recommended version of Lit.
eleventyConfig.addCollection('docs-unversioned', function (collection) {
const docs = collection
.getFilteredByGlob(['site/docs/unversioned/**'])
.sort(sortDocs);
for (const page of docs) {
documentByUrl.set(page.url, page);
Expand Down Expand Up @@ -379,7 +437,7 @@ ${content}

addApiShortcode(
'api',
'/docs/api',
'/docs/v2/api',
// Don't use require() because of Node caching in watch mode.
JSON.parse(
fsSync.readFileSync('../lit-dev-api/api-data/lit-2/symbols.json', 'utf8')
Expand Down Expand Up @@ -487,8 +545,10 @@ ${content}
ENV.eleventyOutDir + '/docs/*/index.html',
ENV.eleventyOutDir + '/docs/v1/introduction.html',
ENV.eleventyOutDir + '/docs/v1/*/index.html',
ENV.eleventyOutDir + '/docs/v2/introduction.html',
ENV.eleventyOutDir + '/docs/v2/*/index.html',
],
{ignore: ENV.eleventyOutDir + '/docs/v1/index.html'}
{ignore: ENV.eleventyOutDir + '/docs/(v1|v2)/index.html'}
)
).filter(
// TODO(aomarks) This is brittle, we need a way to annotate inside an md
Expand Down
Loading