From 1afd294df6ebae002a4b173514f63388b8d3dcbc Mon Sep 17 00:00:00 2001 From: William Wagner <44823142+williamw2@users.noreply.github.com> Date: Mon, 7 Mar 2022 10:08:34 -0800 Subject: [PATCH] Add fast command buffer (#5708) --- .../web-components/fast-ssr/server/server.ts | 89 ++--- .../fast-command-buffer/index.fixture.html | 306 ++++++++++++++++++ .../fast-ssr/src/fast-command-buffer/index.ts | 149 +++++++++ 3 files changed, 502 insertions(+), 42 deletions(-) create mode 100644 packages/web-components/fast-ssr/src/fast-command-buffer/index.fixture.html create mode 100644 packages/web-components/fast-ssr/src/fast-command-buffer/index.ts diff --git a/packages/web-components/fast-ssr/server/server.ts b/packages/web-components/fast-ssr/server/server.ts index 0507d622326..b83fdc77a57 100644 --- a/packages/web-components/fast-ssr/server/server.ts +++ b/packages/web-components/fast-ssr/server/server.ts @@ -23,50 +23,55 @@ function handleRequest(req: Request, res: Response) { }); } -function handleStyleRequest(req: Request, res: Response) { - res.set("Content-Type", "text/html"); - fs.readFile( - path.resolve(__dirname, "./src/fast-style/index.fixture.html"), - { encoding: "utf8" }, - (err, data) => { - const stream = (Readable as any).from(data); - stream.on("readable", function (this: any) { - while ((data = this.read())) { - res.write(data); - } - }); - stream.on("close", () => res.end()); - stream.on("error", (e: Error) => { - console.error(e); - process.exit(1); - }); - } - ); -} - -function handleStyleScriptRequest(req: Request, res: Response) { - res.set("Content-Type", "application/javascript"); - fs.readFile( - path.resolve(__dirname, "./dist/esm/fast-style/index.js"), - { encoding: "utf8" }, - (err, data) => { - const stream = (Readable as any).from(data); - stream.on("readable", function (this: any) { - while ((data = this.read())) { - res.write(data); - } - }); - stream.on("close", () => res.end()); - stream.on("error", (e: Error) => { - console.error(e); - process.exit(1); - }); - } - ); +function handlePathRequest( + mapPath: string, + contentType: string, + req: Request, + res: Response +) { + res.set("Content-Type", contentType); + fs.readFile(path.resolve(__dirname, mapPath), { encoding: "utf8" }, (err, data) => { + const stream = (Readable as any).from(data); + stream.on("readable", function (this: any) { + while ((data = this.read())) { + res.write(data); + } + }); + stream.on("close", () => res.end()); + stream.on("error", (e: Error) => { + console.error(e); + process.exit(1); + }); + }); } const app = express(); app.get("/", handleRequest); -app.get("/fast-style", handleStyleRequest); -app.get("/fast-style.js", handleStyleScriptRequest); +app.get("/fast-style", (req: Request, res: Response) => + handlePathRequest("./src/fast-style/index.fixture.html", "text/html", req, res) +); +app.get("/fast-style.js", (req: Request, res: Response) => + handlePathRequest( + "./dist/esm/fast-style/index.js", + "application/javascript", + req, + res + ) +); +app.get("/fast-command-buffer", (req: Request, res: Response) => + handlePathRequest( + "./src/fast-command-buffer/index.fixture.html", + "text/html", + req, + res + ) +); +app.get("/fast-command-buffer.js", (req: Request, res: Response) => + handlePathRequest( + "./dist/esm/fast-command-buffer/index.js", + "application/javascript", + req, + res + ) +); app.listen(PORT); diff --git a/packages/web-components/fast-ssr/src/fast-command-buffer/index.fixture.html b/packages/web-components/fast-ssr/src/fast-command-buffer/index.fixture.html new file mode 100644 index 00000000000..641b897e4db --- /dev/null +++ b/packages/web-components/fast-ssr/src/fast-command-buffer/index.fixture.html @@ -0,0 +1,306 @@ + + + + + + + + + + + +
+ + + + + + + +
+
+ + + + + diff --git a/packages/web-components/fast-ssr/src/fast-command-buffer/index.ts b/packages/web-components/fast-ssr/src/fast-command-buffer/index.ts new file mode 100644 index 00000000000..a44beeb69f1 --- /dev/null +++ b/packages/web-components/fast-ssr/src/fast-command-buffer/index.ts @@ -0,0 +1,149 @@ +const FASTCommandBufferAttributeName: string = "data-fast-buffer-events"; + +interface CommandCache { + originalNode: HTMLElement; + event: Event; + attachedNode: HTMLElement | null; +} + +/** + * Component for recording user events on SSR rendered FAST components which have not yet hydrated and replaying those + * events when they have. + * During SSR an instance of the component should be placed as a direct child within every template + * that contains children with behaviors bound to user generated events (click, mouseover, focus, etc). When those child element + * tags are rendered FASTCommandBufferAttributeName attribute must be included that lists the events which the element needs to + * have recorded as a comma delimited list (i.e.