From 64c6cd3e9f406434a0faf01fc7242dcfe4e90416 Mon Sep 17 00:00:00 2001 From: Sarah Miller Date: Mon, 24 Mar 2025 11:46:21 -0400 Subject: [PATCH 1/4] add helper functions to video card component --- web-components/video-card/video-card.js | 79 ++++++++++++++----------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/web-components/video-card/video-card.js b/web-components/video-card/video-card.js index 91d1d0e7..dd2960d7 100644 --- a/web-components/video-card/video-card.js +++ b/web-components/video-card/video-card.js @@ -3,8 +3,44 @@ fetch("web-components/video-card/video-card.html") .then(stream => stream.text()) .then(text => createComponent(text)) -// Create web component +/** + * Creates a web component using a given HTML template. + * @param {string} html - The HTML template. + * @returns {void} + */ function createComponent(html) { + + /** + * Sets the content of an element based on a CSS selector. + * @param {string} cssSelector - The CSS selector of the element to set the content for. + * @param {string} content - The content to set for the element. + * @param {boolean} shadow - A boolean indicating whether to use the shadow DOM for the element. + * @returns {void} + */ + function setContent(cssSelector, content, shadow) { + const selector = shadow.querySelector(cssSelector); + selector.textContent = content; + } + + /** + * Sets the link of an element based on a CSS selector. + * @param {string} url - The link url. + * @param {string} linkText - The link text. + * @param {string} cssSelector - The CSS selector of the element to set the content for. + * @param {string} name - The name of the element containing the link. + * @param {boolean} shadow - A boolean indicating whether to use the shadow DOM for the element. + * @returns {void} + */ + function setLink(url, linkText, cssSelector, name, shadow) { + if (url != undefined) { + const linkObj = shadow.querySelector(cssSelector); + linkObj.href = url; + const ariaText = (linkText != 'now') ? `Watch ${name}, ${linkText}` : `Watch ${name}`; // Change link text if defined + linkObj.setAttribute('aria-label', ariaText); + linkObj.textContent = `Watch ${linkText} →`; + } + } + // Web component class class VideoCard extends HTMLElement { @@ -38,44 +74,17 @@ function createComponent(html) { // ); // Set video name - const videoName = shadow.querySelector('.video-name'); - videoName.textContent = this.name; - + setContent('.video-name', this.name, shadow); // Set video desc - const videoDesc = shadow.querySelector('.video-desc'); - videoDesc.textContent = this.desc; - + setContent('.video-desc', this.desc, shadow); // Set video level - const videoLevel = shadow.querySelector('.video-level'); - videoLevel.textContent = this.level; - + setContent('.video-level', this.level, shadow); // Set video time - const videoTime = shadow.querySelector('.video-time'); - videoTime.textContent = this.time; - + setContent('.video-time', this.time, shadow); // Set video links - const videoLink = shadow.querySelector('.video-link'); - const videoLink2 = shadow.querySelector('.video-link-2'); - const videoLink3 = shadow.querySelector('.video-link-3'); - const links = [ - [this.link, this.linktext, videoLink], - [this.link2, this.linktext2, videoLink2], - [this.link3, this.linktext3, videoLink3] - ] - - links.forEach(link => { - const url = link[0]; - const linkText = link[1]; - const linkObj = link[2]; - - // Check if urls have been defined - if (url != undefined) { - linkObj.href = url; - const ariaText = (linkText != 'now') ? `Watch ${this.name}, ${linkText}` : `Watch ${this.name}`; // Change link text if defined - linkObj.setAttribute('aria-label', ariaText); - linkObj.textContent = `Watch ${linkText} →`; - } - }) + setLink(this.link, this.linktext, '.video-link', this.name, shadow); + setLink(this.link2, this.linktext2, '.video-link-2', this.name, shadow); + setLink(this.link3, this.linktext3, '.video-link-3', this.name, shadow); } } From 788d760edca1a1e6733ec0cbdfce57e4c7a6c469 Mon Sep 17 00:00:00 2001 From: Sarah Miller Date: Mon, 24 Mar 2025 11:50:37 -0400 Subject: [PATCH 2/4] document video card component class --- web-components/video-card/video-card.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/web-components/video-card/video-card.js b/web-components/video-card/video-card.js index dd2960d7..c78b3c4a 100644 --- a/web-components/video-card/video-card.js +++ b/web-components/video-card/video-card.js @@ -41,10 +41,10 @@ function createComponent(html) { } } - // Web component class + // Web component class representing a video card. class VideoCard extends HTMLElement { - // Creates element with default values + // Creates an instance of VideoCard constructor() { super(); this.level = 'Varies'; @@ -52,18 +52,28 @@ function createComponent(html) { this.linktext = 'now'; } - // Return array of properties to observe + /** + * Returns an array of properties to observe. + * @returns {Array} An array of property names. + */ static get observedAttributes() { return ['name', 'desc', 'level', 'time', 'link', 'linktext', 'link2', 'linktext2', 'link3', 'linktext3']; } - // Called when an attribute is defined or changed + /** + * Called when an attribute is defined or changed. + * @param {string} property - The name of the attribute. + * @param {string} oldValue - The old value of the attribute. + * @param {string} newValue - The new value of the attribute. + */ attributeChangedCallback(property, oldValue, newValue) { if (oldValue === newValue) return; this[property] = newValue; } - // Invoked when element is added to document + /** + * Invoked when the element is added to the document. + */ connectedCallback() { // Create shadow root for element const shadow = this.attachShadow({mode: 'closed'}); @@ -88,6 +98,7 @@ function createComponent(html) { } } + // Define new VideoCard element customElements.define('video-card', VideoCard); } From e633d0c116ba608fd03d4400b6e483a0367333af Mon Sep 17 00:00:00 2001 From: Sarah Miller Date: Mon, 24 Mar 2025 12:47:41 -0400 Subject: [PATCH 3/4] document course card component --- web-components/course-card/course-card.js | 38 ++++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/web-components/course-card/course-card.js b/web-components/course-card/course-card.js index 782c7327..ba94660a 100644 --- a/web-components/course-card/course-card.js +++ b/web-components/course-card/course-card.js @@ -3,34 +3,61 @@ fetch("web-components/course-card/course-card.html") .then(stream => stream.text()) .then(text => createComponent(text)) -// Create web component +/** + * Creates a web component using a given HTML template. + * @param {string} html - The HTML template. + * @returns {void} + */ function createComponent(html) { + /** + * Sets the content of an element based on a CSS selector. + * @param {string} cssSelector - The CSS selector of the element to set the content for. + * @param {string} content - The content to set for the element. + * @param {boolean} shadow - A boolean indicating whether to use the shadow DOM for the element. + * @returns {void} + */ function setContent(cssSelector, content, shadow) { const selector = shadow.querySelector(cssSelector); selector.textContent = content; } + /** + * Sets the link of an element based on a CSS selector. + * @param {string} cssSelector - The CSS selector of the element to set the link for. + * @param {string} url - The link url. + * @param {string} name - The name of the element containing the link. + * @param {boolean} shadow - A boolean indicating whether to use the shadow DOM for the element. + * @returns {void} + */ function setLink(cssSelector, url, name, shadow) { const link = shadow.querySelector(cssSelector); link.href = url; link.setAttribute('aria-label', `Learn more about ${name}`); } - // Web component class + // Web component class representing a course card. class CourseCard extends HTMLElement { - // Creates element with default values + // Creates an instance of CourseCard constructor() { super(); } - // Return array of properties to observe + /** + * Returns an array of properties to observe. + * @returns {Array} An array of property names. + */ static get observedAttributes() { return ['name', 'desc', 'imgsrc', 'level', 'cost', 'badge', 'time', 'link', 'livelevel', 'livecost', 'livebadge', 'livetime', 'livelink']; } - // Called when an attribute is defined or changed + /** + * Called when an attribute is defined or changed. + * @param {string} property - The name of the attribute. + * @param {string} oldValue - The old value of the attribute. + * @param {string} newValue - The new value of the attribute. + */ attributeChangedCallback(property, oldValue, newValue) { if (oldValue === newValue) return; this[property] = newValue; @@ -82,5 +109,6 @@ function createComponent(html) { } } + // Define new CourseCard element customElements.define('course-card', CourseCard); } \ No newline at end of file From 729d9c928c5d86ee2adf3642e8a8fa12c04f1c63 Mon Sep 17 00:00:00 2001 From: Sarah Miller Date: Mon, 24 Mar 2025 12:51:00 -0400 Subject: [PATCH 4/4] setImage helper function for course card --- web-components/course-card/course-card.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/web-components/course-card/course-card.js b/web-components/course-card/course-card.js index ba94660a..eb31d3e7 100644 --- a/web-components/course-card/course-card.js +++ b/web-components/course-card/course-card.js @@ -36,6 +36,20 @@ function createComponent(html) { link.setAttribute('aria-label', `Learn more about ${name}`); } + /** + * Sets the content of an element based on a CSS selector. + * @param {string} cssSelector - The CSS selector of the element to set the content for. + * @param {string} src - The image source to set for the element. + * @param {string} name - The name of the element containing the image. + * @param {boolean} shadow - A boolean indicating whether to use the shadow DOM for the element. + * @returns {void} + */ + function setImage(cssSelector, src, name, shadow) { + const courseImg = shadow.querySelector(cssSelector); + courseImg.src = src; + courseImg.setAttribute('alt', `${name} badge`); + } + // Web component class representing a course card. class CourseCard extends HTMLElement { @@ -70,10 +84,7 @@ function createComponent(html) { shadow.innerHTML = html; // Set course img - const courseImg = shadow.querySelector('.course-img'); - courseImg.src = this.imgsrc; - courseImg.setAttribute('alt', `${this.name} badge`); - + setImage('.course-img', this.imgsrc, this.name, shadow); // Set course name setContent('.course-name', this.name, shadow); // Set course desc