Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some followups and polish for the tutorial #65

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
19 changes: 9 additions & 10 deletions tutorials/mastodon-toot-embed/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,23 @@ excerpt: Build out an embeddable Mastodon post using just the url

{% stub %}

In this tutorial, we will walk through the process of creating a custom element that can be used to easily display
Mastodon posts on any website or application.
In this tutorial, we will walk through the process of creating a Web Component that can be used to display Mastodon
posts on any website or application.
Comment on lines +9 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder what this paragraph really adds? Perhaps we can just remove it?


Our aim will be to create a `<toot-embed>` element will allow users to share and display posts (sometimes called
"toots") from the Mastodon social network, and will include features such as the ability to show or hide the user handle
and avatar image, as well as the option to customize the appearance of the toot.
Mastodon is a decentralized and open-source social network that allows users to share short posts, called "toots", and
interact with other users on the network. It is similar to Twitter, but with a focus on privacy, freedom of speech, and
community building.

Our aim will be to create a <toot-embed> element that will allow users to share and display Mastodon posts on other
websites or applications.

Here's an example of a Mastodon toot embed. We'll be making something similar.

<iframe src="https://fosstodon.org/@webcomponentsguide/109660552894549193/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"></iframe><script src="https://fosstodon.org/embed.js" async="async"></script>

We will start by setting up the project files and dependencies, and then move on to defining the Mastodon toot embed
element class, extending the HTMLElement class, and registering the element with the browser. We will also cover adding
properties and methods to the element, using a shadow DOM for improved styling and separation of concerns, and adding
interactivity to the element.

Finally, we will look at integrating the Mastodon toot embed element with a real-world project, including tips for
building and using the element in a production environment.
properties and methods to the element and using a shadow DOM for improved styling.

Throughout this tutorial, we will explore the various features and capabilities of Web Components, and how they can be
used to build reusable and modular components for the web.
Expand Down
92 changes: 29 additions & 63 deletions tutorials/mastodon-toot-embed/properties-and-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ title: Fetching the data

Now we can start fetching the data from the mastodon servers!

We need to make sure that we have a valid URL to get the data from. We'll be using the `src` attribute to store the URL
for the toot. Lets set up getters and setters for `src`.
## Setting up the attribute setter and getter

We'll be using the src attribute to store the URL for the toot. Let's set up getters and setters for src.

```js
class TootEmbedElement extends HTMLElement {
Expand All @@ -22,110 +23,75 @@ class TootEmbedElement extends HTMLElement {
}
// ...

get src() {}
set src(value) {}
get src() {
const src = this.getAttribute("src")
if (!src) return ""

return src
}

set src(value) {
this.setAttribute("src", value)
}
}

TootEmbedElement.define()
```

We want to do two things. Persist the `src` value to a `src` attribute on the element _and_ make sure that the URL isn't
malformed.
## Parsing the URL

To make sure that the URL isn't malformed, we pass it through the URL constructor before returning the attribute value.
To make sure that the URL is valid, we pass it through the URL constructor before returning the attribute value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To make sure that the URL is valid, we pass it through the URL constructor before returning the attribute value.
To always have a valid URL, pass it through the URL constructor before returning the attribute value.


```js
class TootEmbedElement extends HTMLElement {
// ...
static define(tagName = "toot-embed") {
customElements.define(tagName, this)
}

connectedCallback() {
this.textContent = "Hello World!"
}
// ...

get src() {
const src = this.getAttribute("src")
if (!src) return ""

// Check if the URL is valid
return new URL(src, window.location.origin).toString()
}
}

TootEmbedElement.define()
```

And we can persist the value to an attribute using `setAttribute`:
## Fetching the data

Now we can use the fetch method to make a network request and display the data that we receive.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Now we can use the fetch method to make a network request and display the data that we receive.
The fetch method to make a network request and display the data from the response.


```js
class TootEmbedElement extends HTMLElement {
// ...
static define(tagName = "toot-embed") {
customElements.define(tagName, this)
}

connectedCallback() {
this.textContent = "Hello World!"
}

get src() {
const src = this.getAttribute("src")
if (!src) return ""

return new URL(src, window.location.origin).toString()
}
// ...

set src(value) {
this.setAttribute("src", value)
async load() {
const response = await fetch(this.src)
this.textContent = JSON.stringify(await response.json())
}
}

TootEmbedElement.define()
```

Now getting the data from the mastodon servers is a matter of using `fetch` to make a network request and display the
data that we receive.
Finally inside the connectedCallback method we use the load method to retrieve and display data from the src attribute

```js
```
class TootEmbedElement extends HTMLElement {
// ...
static define(tagName = "toot-embed") {
customElements.define(tagName, this)
}
// ...

connectedCallback() {
this.load()
}

// ...
get src() {
const src = this.getAttribute("src")
if (!src) return ""

return new URL(src, window.location.origin).toString()
}

set src(value) {
this.setAttribute("src", value)
}
// ...

async load() {
const response = await fetch(this.src)
this.textContent = JSON.stringify(await response.json())
}
}

TootEmbedElement.define()
```

Now we should be getting data! You should be seeing something like this in your browser:
Now you should be getting data! You should be seeing something like this in your browser:

![A browser screenshot showing the toot-embed component at it's current stage. The example page reads: "Here's an example toot: " followed by a dump of JSON data for a random Mastodon toot.](/images/tutorials/mastodon-toot-embed/fig2.png)
A browser screenshot showing the toot-embed component at it's current stage. The example page reads: "Here's an example
toot: " followed by a dump of JSON data for a random Mastodon toot.

Yuk! Just a bunch of data spilled all over. We're gonna have to make this look prettier. In the next section we'll go
over templating this data into a better looking component.
Yuk! Just a bunch of data spilled all over. We're gonna have to make this look prettier. In the next section, we'll go
over how to template this data into a better looking component.
9 changes: 8 additions & 1 deletion tutorials/mastodon-toot-embed/rendering-the-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,14 @@ You should now see the Mastodon toot data displayed in a more structured and pre
![A browser screenshot showing the toot-embed component at it's current stage. The example page reads: "Here's an example toot: " followed by a display of the Mastodon toot data including the avatar image, display name, and toot content.](/images/tutorials/mastodon-toot-embed/fig3.png)

It's still not very good to look at! The image is way to big and the whole layout is a bit off. Let's add some
rudimentary styles to the component in a `<style>` tag to make it a bit better.
rudimentary styles to the component to make it a bit better.

{% tip %}

To support all modern browser make sure to provide a fallback approach for those browser which does not support the
`CSSStyleSheet` API.

{% endtip %}
Comment on lines +75 to +80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something for us to do here is have a reference section on polyfills, which we can link to for items like this.


```js
const styles = new CSSStyleSheet()
Expand Down