diff --git a/web-components/course-card/course-card.js b/web-components/course-card/course-card.js index 782c7327..eb31d3e7 100644 --- a/web-components/course-card/course-card.js +++ b/web-components/course-card/course-card.js @@ -3,34 +3,75 @@ 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 + /** + * 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 { - // 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; @@ -43,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 @@ -82,5 +120,6 @@ function createComponent(html) { } } + // Define new CourseCard element customElements.define('course-card', CourseCard); } \ No newline at end of file diff --git a/web-components/video-card/video-card.js b/web-components/video-card/video-card.js index 91d1d0e7..c78b3c4a 100644 --- a/web-components/video-card/video-card.js +++ b/web-components/video-card/video-card.js @@ -3,12 +3,48 @@ 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) { - // Web component class + + /** + * 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 representing a video card. class VideoCard extends HTMLElement { - // Creates element with default values + // Creates an instance of VideoCard constructor() { super(); this.level = 'Varies'; @@ -16,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'}); @@ -38,47 +84,21 @@ 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); } } + // Define new VideoCard element customElements.define('video-card', VideoCard); }