Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions web-components/course-card/course-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -82,5 +120,6 @@ function createComponent(html) {
}
}

// Define new CourseCard element
customElements.define('course-card', CourseCard);
}
100 changes: 60 additions & 40 deletions web-components/video-card/video-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,77 @@ 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';
this.time = 'Varies';
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'});
Expand All @@ -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);
}

Expand Down