+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Heading
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Maurisscelerisque varius ornare. Etiam convallis sollicitudin
+ scelerisque.Maecenas in velit vehicula, aliquet orci et, consequat
+ purus. Donec egetsodales lectus, vel sollicitudin ligula.
+ Suspendisse volutpat auctor diam,vel mattis lorem venenatis in.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/web-components/fast-ssr/src/fast-style/index.ts b/packages/web-components/fast-ssr/src/fast-style/index.ts
new file mode 100644
index 00000000000..a987e351dc6
--- /dev/null
+++ b/packages/web-components/fast-ssr/src/fast-style/index.ts
@@ -0,0 +1,77 @@
+import { DOM, StyleTarget } from "@microsoft/fast-element";
+
+interface StyleCache {
+ [key: string]: CSSStyleSheet | string;
+}
+
+/**
+ * The FASTStyle web component that takes attributes:
+ * - css - a string version of the CSS to be applied to the parent web component, this can be omitted if the data-style-id has been used in the DOM as the cached value will be fetched
+ * - data-style-id - a dataset attribute used as an identifier for the CSS attr string
+ */
+export default class FASTStyle extends HTMLElement {
+ static cache: StyleCache = {};
+ static hashIdDataSetName: string = "data-style-id";
+
+ constructor() {
+ super();
+
+ const hashId: string = this.getAttribute(FASTStyle.hashIdDataSetName) as string;
+ const css: string = this.getAttribute("css") as string;
+ this.registerStyles(hashId, css);
+ }
+
+ /**
+ * Register styles if they are not part of the cache and attach them
+ */
+ registerStyles = (hashId: string, css: string): void => {
+ if (DOM.supportsAdoptedStyleSheets) {
+ if (!(hashId in FASTStyle.cache)) {
+ this.memoizeAdoptedStylesheetStyles(hashId, css);
+ }
+ this.attachAdoptedStylesheetStyles(this.parentNode as StyleTarget, hashId);
+ } else {
+ if (!(hashId in FASTStyle.cache)) {
+ this.memoizeStyleElementStyles(hashId, css);
+ }
+ this.attachStyleElementStyles(this.parentNode as StyleTarget, hashId);
+ }
+ };
+
+ /**
+ * Memoize CSSStyleSheets
+ */
+ memoizeAdoptedStylesheetStyles(hashId: string, css: string) {
+ const sheet = new CSSStyleSheet();
+ (sheet as any).replaceSync(css);
+ FASTStyle.cache[hashId] = sheet;
+ }
+
+ /**
+ * Attach CSSStyleSheets
+ */
+ attachAdoptedStylesheetStyles(shadowRoot: StyleTarget, hashId: string) {
+ shadowRoot.adoptedStyleSheets = [
+ ...shadowRoot.adoptedStyleSheets!,
+ FASTStyle.cache[hashId] as CSSStyleSheet,
+ ];
+ }
+
+ /**
+ * Memoize css strings
+ */
+ memoizeStyleElementStyles(hashId: string, css: string) {
+ FASTStyle.cache[hashId] = css;
+ }
+
+ /**
+ * Attach style elements
+ */
+ attachStyleElementStyles(shadowRoot: StyleTarget, hashId: string) {
+ const element = document.createElement("style");
+ element.innerHTML = FASTStyle.cache[hashId] as string;
+ shadowRoot.append(element);
+ }
+}
+
+customElements.define("fast-style", FASTStyle);
diff --git a/packages/web-components/fast-ssr/test/fast-style.spec.ts b/packages/web-components/fast-ssr/test/fast-style.spec.ts
new file mode 100644
index 00000000000..08f74b18e39
--- /dev/null
+++ b/packages/web-components/fast-ssr/test/fast-style.spec.ts
@@ -0,0 +1,62 @@
+import { expect, test } from "@playwright/test"
+
+test("Check that the first element has styles assigned", async ({ page }) => {
+ await page.goto("/fast-style");
+
+ const cards = page.locator("fast-card");
+ const styles = await cards.evaluateAll((cardList) => {
+ return cardList.map((card) => {
+ return window.getComputedStyle(card, null).getPropertyValue("background-color");
+ });
+ });
+
+ expect(styles[0]).toEqual("rgb(26, 26, 26)");
+});
+test("Check that the nested element in the first element has styles assigned", async ({ page }) => {
+ await page.goto("/fast-style");
+
+ const cards = page.locator("fast-card");
+ const styles = await cards.evaluateAll((cardList) => {
+ return cardList.map((card) => {
+ return window.getComputedStyle(
+ (card.shadowRoot?.querySelector("fast-button") as Element), null
+ ).getPropertyValue("background-color");
+ });
+ });
+
+ expect(styles[0]).toEqual("rgb(43, 43, 43)");
+});
+test("Check that all elements have styles assigned", async ({ page }) => {
+ await page.goto("/fast-style");
+
+ const cards = page.locator("fast-card");
+ const styles = await cards.evaluateAll((cardList) => {
+ return cardList.map((card) => {
+ return window.getComputedStyle(card, null).getPropertyValue("background-color");
+ });
+ });
+
+ expect(styles).toHaveLength(10);
+
+ styles.forEach((style) => {
+ expect(style).toEqual("rgb(26, 26, 26)");
+ });
+});
+test("Check that all nested elements have styles assigned", async ({ page}) => {
+ await page.goto("/fast-style");
+
+ const cards = page.locator("fast-card");
+ const styles = await cards.evaluateAll((cardList) => {
+ return cardList.map((card) => {
+ return window.getComputedStyle(
+ (card.shadowRoot?.querySelector("fast-button") as Element), null
+ ).getPropertyValue("background-color");
+ });
+ });
+
+ expect(styles).toHaveLength(10);
+
+ styles.forEach((style) => {
+ expect(style).toEqual("rgb(43, 43, 43)");
+ });
+});
diff --git a/packages/web-components/fast-ssr/webpack.fast-style.config.cjs b/packages/web-components/fast-ssr/webpack.fast-style.config.cjs
new file mode 100644
index 00000000000..91fa9f3dd3a
--- /dev/null
+++ b/packages/web-components/fast-ssr/webpack.fast-style.config.cjs
@@ -0,0 +1,36 @@
+const path = require("path");
+const srcDir = path.resolve(__dirname, "./src");
+const outDir = path.resolve(__dirname, "./dist");
+
+/**
+ * This file exports the minified fast-style web component
+ */
+module.exports = {
+ entry: {
+ "fast-style": path.resolve(srcDir, "./fast-style/index.ts"),
+ },
+ output: {
+ path: outDir,
+ filename: "[name].min.js",
+ },
+ mode: "production",
+ module: {
+ rules: [
+ {
+ test: /.ts$/,
+ use: [
+ {
+ loader: "ts-loader",
+ options: {
+ onlyCompileBundledFiles: true,
+ configFile: "tsconfig.json",
+ },
+ },
+ ],
+ },
+ ],
+ },
+ resolve: {
+ extensions: [".js", ".ts", ".json"],
+ },
+};
From 99c7c6bb2e5f5ac4297857fe8e76b8df72f3487c Mon Sep 17 00:00:00 2001
From: Jane Chu <7559015+janechu@users.noreply.github.com>
Date: Mon, 14 Feb 2022 15:37:18 -0800
Subject: [PATCH 2/6] privatize methods and static vars
---
.../fast-ssr/src/fast-style/index.ts | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/packages/web-components/fast-ssr/src/fast-style/index.ts b/packages/web-components/fast-ssr/src/fast-style/index.ts
index a987e351dc6..215c5958c7e 100644
--- a/packages/web-components/fast-ssr/src/fast-style/index.ts
+++ b/packages/web-components/fast-ssr/src/fast-style/index.ts
@@ -10,8 +10,8 @@ interface StyleCache {
* - data-style-id - a dataset attribute used as an identifier for the CSS attr string
*/
export default class FASTStyle extends HTMLElement {
- static cache: StyleCache = {};
- static hashIdDataSetName: string = "data-style-id";
+ private static cache: StyleCache = {};
+ private static hashIdDataSetName: string = "data-style-id";
constructor() {
super();
@@ -24,7 +24,7 @@ export default class FASTStyle extends HTMLElement {
/**
* Register styles if they are not part of the cache and attach them
*/
- registerStyles = (hashId: string, css: string): void => {
+ private registerStyles = (hashId: string, css: string): void => {
if (DOM.supportsAdoptedStyleSheets) {
if (!(hashId in FASTStyle.cache)) {
this.memoizeAdoptedStylesheetStyles(hashId, css);
@@ -41,7 +41,7 @@ export default class FASTStyle extends HTMLElement {
/**
* Memoize CSSStyleSheets
*/
- memoizeAdoptedStylesheetStyles(hashId: string, css: string) {
+ private memoizeAdoptedStylesheetStyles(hashId: string, css: string) {
const sheet = new CSSStyleSheet();
(sheet as any).replaceSync(css);
FASTStyle.cache[hashId] = sheet;
@@ -50,7 +50,7 @@ export default class FASTStyle extends HTMLElement {
/**
* Attach CSSStyleSheets
*/
- attachAdoptedStylesheetStyles(shadowRoot: StyleTarget, hashId: string) {
+ private attachAdoptedStylesheetStyles(shadowRoot: StyleTarget, hashId: string) {
shadowRoot.adoptedStyleSheets = [
...shadowRoot.adoptedStyleSheets!,
FASTStyle.cache[hashId] as CSSStyleSheet,
@@ -60,14 +60,14 @@ export default class FASTStyle extends HTMLElement {
/**
* Memoize css strings
*/
- memoizeStyleElementStyles(hashId: string, css: string) {
+ private memoizeStyleElementStyles(hashId: string, css: string) {
FASTStyle.cache[hashId] = css;
}
/**
* Attach style elements
*/
- attachStyleElementStyles(shadowRoot: StyleTarget, hashId: string) {
+ private attachStyleElementStyles(shadowRoot: StyleTarget, hashId: string) {
const element = document.createElement("style");
element.innerHTML = FASTStyle.cache[hashId] as string;
shadowRoot.append(element);
From 3e7fc9e0c7bc7c756ade3a2af1965b9d0b27e181 Mon Sep 17 00:00:00 2001
From: Jane Chu <7559015+janechu@users.noreply.github.com>
Date: Mon, 14 Feb 2022 15:45:22 -0800
Subject: [PATCH 3/6] move attr inspection to connectedCallback
---
packages/web-components/fast-ssr/src/fast-style/index.ts | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/packages/web-components/fast-ssr/src/fast-style/index.ts b/packages/web-components/fast-ssr/src/fast-style/index.ts
index 215c5958c7e..93988026103 100644
--- a/packages/web-components/fast-ssr/src/fast-style/index.ts
+++ b/packages/web-components/fast-ssr/src/fast-style/index.ts
@@ -13,9 +13,10 @@ export default class FASTStyle extends HTMLElement {
private static cache: StyleCache = {};
private static hashIdDataSetName: string = "data-style-id";
- constructor() {
- super();
-
+ /**
+ * @internal
+ */
+ public connectedCallback(): void {
const hashId: string = this.getAttribute(FASTStyle.hashIdDataSetName) as string;
const css: string = this.getAttribute("css") as string;
this.registerStyles(hashId, css);
From 0e0d7f156437930f995b032d66d9b96a2a9b2b9b Mon Sep 17 00:00:00 2001
From: Jane Chu <7559015+janechu@users.noreply.github.com>
Date: Mon, 14 Feb 2022 16:55:01 -0800
Subject: [PATCH 4/6] remove DOM dependency
---
.../fast-ssr/src/fast-style/index.ts | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/packages/web-components/fast-ssr/src/fast-style/index.ts b/packages/web-components/fast-ssr/src/fast-style/index.ts
index 93988026103..cb480301651 100644
--- a/packages/web-components/fast-ssr/src/fast-style/index.ts
+++ b/packages/web-components/fast-ssr/src/fast-style/index.ts
@@ -1,5 +1,3 @@
-import { DOM, StyleTarget } from "@microsoft/fast-element";
-
interface StyleCache {
[key: string]: CSSStyleSheet | string;
}
@@ -12,6 +10,9 @@ interface StyleCache {
export default class FASTStyle extends HTMLElement {
private static cache: StyleCache = {};
private static hashIdDataSetName: string = "data-style-id";
+ private static supportsAdoptedStyleSheets: boolean =
+ Array.isArray((document as any).adoptedStyleSheets) &&
+ "replace" in CSSStyleSheet.prototype;
/**
* @internal
@@ -26,16 +27,16 @@ export default class FASTStyle extends HTMLElement {
* Register styles if they are not part of the cache and attach them
*/
private registerStyles = (hashId: string, css: string): void => {
- if (DOM.supportsAdoptedStyleSheets) {
+ if (FASTStyle.supportsAdoptedStyleSheets) {
if (!(hashId in FASTStyle.cache)) {
this.memoizeAdoptedStylesheetStyles(hashId, css);
}
- this.attachAdoptedStylesheetStyles(this.parentNode as StyleTarget, hashId);
+ this.attachAdoptedStylesheetStyles(this.parentNode as ShadowRoot, hashId);
} else {
if (!(hashId in FASTStyle.cache)) {
this.memoizeStyleElementStyles(hashId, css);
}
- this.attachStyleElementStyles(this.parentNode as StyleTarget, hashId);
+ this.attachStyleElementStyles(this.parentNode as ShadowRoot, hashId);
}
};
@@ -51,9 +52,9 @@ export default class FASTStyle extends HTMLElement {
/**
* Attach CSSStyleSheets
*/
- private attachAdoptedStylesheetStyles(shadowRoot: StyleTarget, hashId: string) {
- shadowRoot.adoptedStyleSheets = [
- ...shadowRoot.adoptedStyleSheets!,
+ private attachAdoptedStylesheetStyles(shadowRoot: ShadowRoot, hashId: string) {
+ (shadowRoot as any).adoptedStyleSheets = [
+ ...(shadowRoot as any).adoptedStyleSheets!,
FASTStyle.cache[hashId] as CSSStyleSheet,
];
}
@@ -68,7 +69,7 @@ export default class FASTStyle extends HTMLElement {
/**
* Attach style elements
*/
- private attachStyleElementStyles(shadowRoot: StyleTarget, hashId: string) {
+ private attachStyleElementStyles(shadowRoot: ShadowRoot, hashId: string) {
const element = document.createElement("style");
element.innerHTML = FASTStyle.cache[hashId] as string;
shadowRoot.append(element);
From 2155d9fc213cced1bbdaa017763004680b38f274 Mon Sep 17 00:00:00 2001
From: Jane Chu <7559015+janechu@users.noreply.github.com>
Date: Mon, 14 Feb 2022 17:06:48 -0800
Subject: [PATCH 5/6] remove webpack, use compiled ts as module with mimetype
for es6
---
packages/web-components/fast-ssr/package.json | 6 +-----
packages/web-components/fast-ssr/server/server.ts | 6 +++---
.../fast-ssr/src/fast-style/index.fixture.html | 2 +-
3 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/packages/web-components/fast-ssr/package.json b/packages/web-components/fast-ssr/package.json
index 9168f33f0e8..cdcb62fa1ec 100644
--- a/packages/web-components/fast-ssr/package.json
+++ b/packages/web-components/fast-ssr/package.json
@@ -16,7 +16,6 @@
},
"scripts": {
"build": "tsc -b --clean src && tsc -b src",
- "build:fast-style": "webpack --config webpack.fast-style.config.cjs",
"build-server": "tsc -b server",
"pretest": "npm run build-server",
"test": "playwright test -c test",
@@ -36,9 +35,6 @@
"@types/express": "^4.17.13",
"@types/node": "^17.0.17",
"express": "^4.17.1",
- "ts-loader": "^9.2.6",
- "typescript": "^3.8.3",
- "webpack": "^5.68.0",
- "webpack-cli": "^4.9.2"
+ "typescript": "^3.8.3"
}
}
diff --git a/packages/web-components/fast-ssr/server/server.ts b/packages/web-components/fast-ssr/server/server.ts
index 833f9a53ff2..866fa10b5e8 100644
--- a/packages/web-components/fast-ssr/server/server.ts
+++ b/packages/web-components/fast-ssr/server/server.ts
@@ -45,9 +45,9 @@ function handleStyleRequest(req: Request, res: Response) {
}
function handleStyleScriptRequest(req: Request, res: Response) {
- res.set("Content-Type", "text/plain");
+ res.set("Content-Type", "application/javascript");
fs.readFile(
- path.resolve(__dirname, "./dist/fast-style.min.js"),
+ path.resolve(__dirname, "./dist/fast-style/index.js"),
{ encoding: "utf8" },
(err, data) => {
const stream = (Readable as any).from(data);
@@ -68,5 +68,5 @@ function handleStyleScriptRequest(req: Request, res: Response) {
const app = express();
app.get("/", handleRequest);
app.get("/fast-style", handleStyleRequest);
-app.get("/fast-style.min.js", handleStyleScriptRequest);
+app.get("/fast-style.js", handleStyleScriptRequest);
app.listen(PORT);
diff --git a/packages/web-components/fast-ssr/src/fast-style/index.fixture.html b/packages/web-components/fast-ssr/src/fast-style/index.fixture.html
index 78b1da25b7b..92820fa5ab9 100644
--- a/packages/web-components/fast-ssr/src/fast-style/index.fixture.html
+++ b/packages/web-components/fast-ssr/src/fast-style/index.fixture.html
@@ -121,7 +121,7 @@
display: flex;
"
>
-
+
From 276b0150c41771df2b60b7cbee9e846283f1f308 Mon Sep 17 00:00:00 2001
From: Jane Chu <7559015+janechu@users.noreply.github.com>
Date: Mon, 14 Feb 2022 17:08:07 -0800
Subject: [PATCH 6/6] remove unused webpack config
---
.../fast-ssr/webpack.fast-style.config.cjs | 36 -------------------
1 file changed, 36 deletions(-)
delete mode 100644 packages/web-components/fast-ssr/webpack.fast-style.config.cjs
diff --git a/packages/web-components/fast-ssr/webpack.fast-style.config.cjs b/packages/web-components/fast-ssr/webpack.fast-style.config.cjs
deleted file mode 100644
index 91fa9f3dd3a..00000000000
--- a/packages/web-components/fast-ssr/webpack.fast-style.config.cjs
+++ /dev/null
@@ -1,36 +0,0 @@
-const path = require("path");
-const srcDir = path.resolve(__dirname, "./src");
-const outDir = path.resolve(__dirname, "./dist");
-
-/**
- * This file exports the minified fast-style web component
- */
-module.exports = {
- entry: {
- "fast-style": path.resolve(srcDir, "./fast-style/index.ts"),
- },
- output: {
- path: outDir,
- filename: "[name].min.js",
- },
- mode: "production",
- module: {
- rules: [
- {
- test: /.ts$/,
- use: [
- {
- loader: "ts-loader",
- options: {
- onlyCompileBundledFiles: true,
- configFile: "tsconfig.json",
- },
- },
- ],
- },
- ],
- },
- resolve: {
- extensions: [".js", ".ts", ".json"],
- },
-};