From 15beac8e632f74ec60f979efc97a6d40693172ff Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Mon, 3 Apr 2023 11:31:58 -0400 Subject: [PATCH 1/3] feat: allow embedded ReadAlong in element Small caveat, you *must* use the element to enclose it even though this is optional for standalone ReadAlong files. --- .../web-component/cypress/e2e/embedded.cy.js | 61 ++++++ .../read-along-component/read-along.tsx | 12 +- packages/web-component/src/utils/utils.ts | 10 +- .../test-data/ej-fra/index-embedded.html | 191 ++++++++++++++++++ 4 files changed, 270 insertions(+), 4 deletions(-) create mode 100644 packages/web-component/cypress/e2e/embedded.cy.js create mode 100644 packages/web-component/test-data/ej-fra/index-embedded.html diff --git a/packages/web-component/cypress/e2e/embedded.cy.js b/packages/web-component/cypress/e2e/embedded.cy.js new file mode 100644 index 00000000..25e50b57 --- /dev/null +++ b/packages/web-component/cypress/e2e/embedded.cy.js @@ -0,0 +1,61 @@ +context("The Readalong Component", () => { + const EXPECTED_LOADING_TIME = 2000; // ms + const FOR_PAGE_TURN_ANIMATION = 500; // ms + const FOR_ERIC_TO_TALK_A_BIT = 3000; // ms + + beforeEach(() => { + cy.visit("/ej-fra/index-embedded.html"); + }); + + it("should load successfully", () => { + cy.readalongElement().should("be.visible"); + + cy.readalong().within(() => { + cy.contains("Page"); + }); + }); + + it("should play the entire ReadAlong", () => { + cy.wait(EXPECTED_LOADING_TIME); + + cy.readalong().within(() => { + cy.get("[data-cy=play-button]").click(); + cy.wait(FOR_ERIC_TO_TALK_A_BIT); + cy.get("[data-cy=stop-button]").click(); + }); + }); + + it("should play a single word when clicked", () => { + cy.wait(EXPECTED_LOADING_TIME); + + cy.readalong().contains("technologies").click(); + }); + + describe("the progress bar", () => { + it("should skip ahead when clicked", () => { + cy.wait(EXPECTED_LOADING_TIME); + + cy.readalong().within(() => { + cy.get("[data-cy=play-button]").click(); + cy.get("[data-cy=page-count__current]") + .filter("*:visible") + .invoke("text") + .should("eq", "1"); + + cy.get("[data-cy=progress-bar]") + .as("progress-bar") + .then((el) => { + // click 3/4 of the way in the readalong (should be second page) + cy.get("@progress-bar").click(el.width() * 0.75, el.height() * 0.5); + }); + cy.get("[data-cy=stop-button]").click(); + cy.wait(FOR_PAGE_TURN_ANIMATION); + + cy.get("[data-cy=page-count__current]") + .filter("*:visible") + .invoke("text") + .should("eq", "2"); + }); + }); + }); +}); diff --git a/packages/web-component/src/components/read-along-component/read-along.tsx b/packages/web-component/src/components/read-along-component/read-along.tsx index 2ba1584d..e7f1a6d7 100644 --- a/packages/web-component/src/components/read-along-component/read-along.tsx +++ b/packages/web-component/src/components/read-along-component/read-along.tsx @@ -15,6 +15,7 @@ import { import { parseRAS, Sprite, + extractPages, extractAlignment, isFileAvailable, } from "../../utils/utils"; @@ -850,9 +851,11 @@ export class ReadAlongComponent { this.playbackRateRange = 15; } - // Parse the text to be displayed // TODO: if parseRAS has an error, we need ERROR_PARSING - this.parsed_text = await parseRAS(this.href); + // Parse the text to be displayed + const text = this.el.querySelector("text"); + if (text) this.parsed_text = extractPages(text); + else this.parsed_text = await parseRAS(this.href); if (this.parsed_text === null) { this.parsed_text = []; this.assetsStatus.RAS = ERROR_LOADING; @@ -1374,7 +1377,10 @@ export class ReadAlongComponent { } /> ); - } else if (child.nodeName === "w") { + } else if (child.nodeName === "w" || child.nodeName === "W") { + /* It may be uppercase for embedded markup, because in + that case it has been parsed as "HTML". See + https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName */ return ( { } /** - * Return sentences from readalong XML file + * Return pages from readalong XML file * @param {string} - the path to the readalong file */ export async function parseRAS(path: string): Promise> { @@ -27,6 +27,14 @@ export async function parseRAS(path: string): Promise> { let xmlDocument = await response.text(); let parser = new DOMParser(); let xml = parser.parseFromString(xmlDocument, "text/xml"); + return extractPages(xml); +} + +/** + * Return pages from parsed XML + * @param {xml} - the parsed XML (could be an element) + */ +export function extractPages(xml: Document | Element): Array { let parsed_pages = Array.from(xml.querySelectorAll("div[type=page]")).map( (page) => { let img = page.querySelector("graphic[url]"); diff --git a/packages/web-component/test-data/ej-fra/index-embedded.html b/packages/web-component/test-data/ej-fra/index-embedded.html new file mode 100644 index 00000000..7620d06f --- /dev/null +++ b/packages/web-component/test-data/ej-fra/index-embedded.html @@ -0,0 +1,191 @@ + + + + + Insert Title Here + + + + + + Insert Title Here Too + + +
+ +

+ Bonjour. + Je + m'appelle + Éric + Joanis. + Je + suis + programmeur + au + sein + de + l'équipe + des + technologies + pour + les + langues + autochtones + au + CNRC. +

+
+
+

+ J'ai + fait + une + bonne + partie + de + ma + carrière + en + traduction + automatique + statistique, + mais + maintenant + cette + approche + est + déclassée + par + l'apprentissage + profond. + En + ce + moment + je + travaille + + l'alignement + du + hansard + du + Nunavut + pour + produire + un + corpus + bilingue + anglais-inuktitut. + Ce + corpus + permettra + d'entraîner + la + TA, + neuronale + ou + statistique, + ainsi + que + d'autres + applications + de + traitement + du + langage + naturel. +

+

+ En + parallèle, + j'aide + + écrire + des + tests + pour + rendre + le + ReadAlong-Studio + plus + robuste. +

+
+ +
+
+ + + + + From 44f6ce8c8f4f52169b60aebbca323b1254a75499 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Tue, 11 Apr 2023 09:14:41 -0400 Subject: [PATCH 2/3] fix: use only immediate child of --- .../src/components/read-along-component/read-along.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-component/src/components/read-along-component/read-along.tsx b/packages/web-component/src/components/read-along-component/read-along.tsx index e7f1a6d7..35d487e0 100644 --- a/packages/web-component/src/components/read-along-component/read-along.tsx +++ b/packages/web-component/src/components/read-along-component/read-along.tsx @@ -853,7 +853,7 @@ export class ReadAlongComponent { // TODO: if parseRAS has an error, we need ERROR_PARSING // Parse the text to be displayed - const text = this.el.querySelector("text"); + const text = this.el.querySelector("read-along > text"); if (text) this.parsed_text = extractPages(text); else this.parsed_text = await parseRAS(this.href); if (this.parsed_text === null) { From 6567132ba7e338efdc68b56616fc58c4fb5f3f38 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Thu, 5 Oct 2023 00:31:00 -0400 Subject: [PATCH 3/3] chore: bump version --- packages/web-component/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-component/package.json b/packages/web-component/package.json index 880dc3fc..eb2d477a 100644 --- a/packages/web-component/package.json +++ b/packages/web-component/package.json @@ -1,6 +1,6 @@ { "name": "@readalongs/web-component", - "version": "1.0.2", + "version": "1.1.0", "description": "ReadAlong Web Component", "main": "dist/index.cjs.js", "module": "dist/index.js",