Skip to content

Commit

Permalink
feat: allow giscus dynamatically update theme based on book theme
Browse files Browse the repository at this point in the history
  • Loading branch information
MR-Addict committed Jul 27, 2024
1 parent a5c5898 commit 23eb4e3
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 79 deletions.
2 changes: 1 addition & 1 deletion docs/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ giscus.repo-id = "R_kgDOLCxX0Q"
giscus.category = "General"
giscus.category-id = "DIC_kwDOLCxX0c4CdGx-"
giscus.reactions-enabled = "1"
giscus.theme = "light"
giscus.theme = "book"
giscus.lang = "en"
giscus.loading = "eager"
18 changes: 9 additions & 9 deletions docs/src/more-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ In this section, I will show you how to add more apps to this preprocessor.

You may have some other apps that preprocessor doesn't support yet. However, it's very easy to add a new app based on project custom template engine.

What we need to do is put a new app template in the `templates` folder. The template file name should be the app name ended with `.html`.
What we need to do is put a new app template in the **templates** folder. The template file name should be the app name ended with **.html**.

For example we want to add a new app called `youtube`, then we could create a `youtube.html` under `templates` folder.
For example we want to add a new app called **youtube**, then we could create a **youtube.html** under **templates** folder.

We know that we can use an iframe to embed a youtube video. Template file could be like this:

Expand All @@ -25,9 +25,9 @@ We know that we can use an iframe to embed a youtube video. Template file could

> 💥Attention
>
> You can even add `style` and `js` content to the template file. But the `style` and `js` content should be put in the `style` and `js` blocks.
> You can even add **style** and **js** content to the template file. But the style and js content should be put in the style and js **blocks**.
However, we want video `id` and `loading` strategy to be dynamic and loading strategy has default `lazy` value. So we can replace them with placeholders like this:
However, we want video **id** and **loading** strategy to be dynamic and loading strategy has default **lazy** value. So we can replace them with placeholders like this:

```html
<iframe
Expand All @@ -40,19 +40,19 @@ However, we want video `id` and `loading` strategy to be dynamic and loading str
></iframe>
```

The placeholder syntax is similar to a **function call** in programming languages, which is the combination of function `name` and `argument` wrapped by `{%` and `%}`.
The placeholder syntax is similar to a **function call** in programming languages, which is the combination of function **name** and **argument** wrapped by **{%** and **%}**.

**Function name**

The preprocessor reconginzes two function names, `raw` and `markdown`. Which `raw` will keep inner value as it is, `markdown` will treat the inner value as markdown content and render it to be html.
The preprocessor reconginzes two function names, **raw** and **markdown**. Which raw will keep inner value as it is, markdown will treat the inner value as markdown content and render it to be html.

**Function argument**

The inner value is key follwed by a default value in the form of `key=default_value`. If the key is not provided, the default value will be used.
The inner value is key follwed by a default value in the form of **key=default_value**. If the key is not provided, the default value will be used.

So `raw(id)` means the placeholder will be replaced by the value of `id` key and id is not optional because it doesn't have a default value.
So **raw(id)** means the placeholder will be replaced by the value of **id** key and id is not optional because it doesn't have a default value.

`raw(loading=lazy)` means the placeholder will be replaced by the value of `loading` key. If user doesn't provide the value, the default value `lazy` will be used. And means loading is optional.
**raw(loading=lazy)** means the placeholder will be replaced by the value of **loading** key. If user doesn't provide the value, the default value **lazy** will be used. And means loading is optional.

## Build the project

Expand Down
8 changes: 4 additions & 4 deletions docs/src/third-party/bilibili.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

## Options

| Option | Description | Required | Default |
| :------ | :----------- | :------- | :------ |
| id | Video ID | Yes | - - |
| loading | Loading type | No | lazy |
| Option | Description | Required | Default |
| :------ | :------------------------------ | :------- | :------ |
| id | Video ID | Yes | - - |
| loading | Supports **lazy** and **eager** | No | lazy |

## Example

Expand Down
14 changes: 7 additions & 7 deletions docs/src/third-party/codepen.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

## Options

| Option | Description | Required | Default |
| :------ | :------------ | :------- | :------ |
| user | username | Yes | - - |
| slug | Project slug | Yes | - - |
| height | Iframe height | No | 600 |
| theme | Iframe theme | No | dark |
| loading | Loading type | No | lazy |
| Option | Description | Required | Default |
| :------ | :------------------------------ | :------- | :------ |
| user | username | Yes | - - |
| slug | Project slug | Yes | - - |
| height | Iframe height | No | 600 |
| theme | Iframe theme | No | dark |
| loading | Supports **lazy** and **eager** | No | lazy |

## Example

Expand Down
10 changes: 5 additions & 5 deletions docs/src/third-party/codesandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

## Options

| Option | Description | Required | Default |
| :------ | :----------- | :------- | :------ |
| id | Project ID | Yes | - - |
| theme | Iframe theme | No | dark |
| loading | Loading type | No | lazy |
| Option | Description | Required | Default |
| :------ | :------------------------------ | :------- | :------ |
| id | Project ID | Yes | - - |
| theme | Iframe theme | No | dark |
| loading | Supports **lazy** and **eager** | No | lazy |

## Example

Expand Down
28 changes: 14 additions & 14 deletions docs/src/third-party/giscus.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@

## Options

| Option | Description | Required | Default |
| :---------------- | :--------------- | :------- | :------ |
| repo | Repository | Yes | - - |
| repo-id | Repository ID | Yes | - - |
| category | Category | Yes | - - |
| category-id | Category ID | Yes | - - |
| reactions-enabled | Enable reactions | No | 1 |
| theme | Theme | No | light |
| lang | Language | No | en |
| loading | Loading type | No | lazy |
| Option | Description | Required | Default |
| :---------------- | :--------------------------------------- | :------- | :------ |
| repo | Repository | Yes | - - |
| repo-id | Repository ID | Yes | - - |
| category | Category | Yes | - - |
| category-id | Category ID | Yes | - - |
| reactions-enabled | Enable reactions | No | 1 |
| theme | Supports **book**,**light** and **dark** | No | book |
| lang | Language | No | en |
| loading | Supports **lazy** and **eager** | No | lazy |

## Example

<!-- embed ignore begin -->

```text
{% embed giscus repo="MR-Addict/mdbook-embedify" repo-id="R_kgDOLCxX0Q" category="General" category-id="DIC_kwDOLCxX0c4CdGx-" theme="light" loading="eager" %}
{% embed giscus repo="MR-Addict/mdbook-embedify" repo-id="R_kgDOLCxX0Q" category="General" category-id="DIC_kwDOLCxX0c4CdGx-" theme="book" loading="eager" %}
```

<!-- embed ignore end -->
Expand All @@ -36,7 +36,7 @@ giscus.repo-id = "R_kgDOLCxX0Q"
giscus.category = "General"
giscus.category-id = "DIC_kwDOLCxX0c4CdGx-"
giscus.reactions-enabled = "1"
giscus.theme = "light"
giscus.theme = "book"
giscus.lang = "en"
giscus.loading = "eager"
```
Expand All @@ -50,15 +50,15 @@ For exampe:
**node.js installed**

```sh
npx serve book
npx serve book -p 3000
```

Which will serve your book at [http://localhost:3000](http://localhost:3000).

**python installed**

```sh
python -m http.server --directory book
python -m http.server --directory book 8080
```

Which will serve your book at [http://localhost:8080](http://localhost:8080).
1 change: 1 addition & 0 deletions docs/src/third-party/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Third party apps are apps that are hosted on third party sites. Below are all supported third party apps and its detailed options.

- [Gist](gist.md)
- [Vimeo](vimeo.md)
- [Giscus](giscus.md)
- [Youtube](youtube.md)
- [Codepen](codepen.md)
Expand Down
10 changes: 5 additions & 5 deletions docs/src/third-party/stackblitz.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

## Options

| Option | Description | Required | Default |
| :------ | :----------- | :------- | :------ |
| id | Project ID | Yes | - - |
| theme | Iframe theme | No | dark |
| loading | Loading type | No | lazy |
| Option | Description | Required | Default |
| :------ | :------------------------------ | :------- | :------ |
| id | Project ID | Yes | - - |
| theme | Iframe theme | No | dark |
| loading | Supports **lazy** and **eager** | No | lazy |

## Example

Expand Down
8 changes: 4 additions & 4 deletions docs/src/third-party/vimeo.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Vimeo is a video hosting platform that allows you to upload and share videos.

## Options

| Option | Description | Required | Default |
| :------ | :----------- | :------- | :------ |
| id | Video ID | Yes | - - |
| loading | Loading type | No | lazy |
| Option | Description | Required | Default |
| :------ | :------------------------------ | :------- | :------ |
| id | Video ID | Yes | - - |
| loading | Supports **lazy** and **eager** | No | lazy |

## Example

Expand Down
8 changes: 4 additions & 4 deletions docs/src/third-party/youtube.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

## Options

| Option | Description | Required | Default |
| :------ | :----------- | :------- | :------ |
| id | Video ID | Yes | - - |
| loading | Loading type | No | lazy |
| Option | Description | Required | Default |
| :------ | :------------------------------ | :------- | :------ |
| id | Video ID | Yes | - - |
| loading | Supports **lazy** and **eager** | No | lazy |

## Example

Expand Down
37 changes: 16 additions & 21 deletions templates/announcement-banner.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,30 +86,25 @@
background-color: transparent;
}
</style>

<div style="display: none" data-id="{% raw(id) %}" class="announcement-banner" data-theme="{% raw(theme=default) %}">
{% markdown(message) %}
<button type="button">X</button>
</div>

<script>
const banner = document.querySelector(".announcement-banner");
const id = banner.getAttribute("data-id");
const message = banner.querySelector("p").textContent;
const localData = JSON.parse(localStorage.getItem("mdbook-announcement-banner"));

if (!localData || localData.id !== id || localData.hide !== true) {
// update banner display style to be flex
banner.style.display = "flex";

// move banner before page class element slibling
const page = document.querySelector(".page");
page.parentNode.insertBefore(banner, page);

// add event listener to close button
banner.querySelector("button").addEventListener("click", () => {
banner.remove();
localStorage.setItem("mdbook-announcement-banner", JSON.stringify({ id, hide: true, message }));
});
}
(() => {
const banner = document.querySelector(".announcement-banner");
const id = banner.getAttribute("data-id");
const message = banner.querySelector("p").textContent;
const localData = JSON.parse(localStorage.getItem("mdbook-announcement-banner"));

if (!localData || localData.id !== id || localData.hide !== true) {
banner.style.display = "flex";
const page = document.querySelector(".page");
page.parentNode.insertBefore(banner, page);
banner.querySelector("button").addEventListener("click", () => {
banner.remove();
localStorage.setItem("mdbook-announcement-banner", JSON.stringify({ id, hide: true, message }));
});
}
})();
</script>
1 change: 0 additions & 1 deletion templates/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@
margin: 0;
}
</style>

<footer>{% markdown(message) %}</footer>
19 changes: 17 additions & 2 deletions templates/giscus.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
margin-top: 6rem;
}
</style>

<script
src="{% raw(src=https://giscus.app/client.js) %}"
data-repo="{% raw(repo) %}"
Expand All @@ -15,9 +14,25 @@
data-reactions-enabled="{% raw(reactions-enabled=1) %}"
data-emit-metadata="0"
data-input-position="bottom"
data-theme="{% raw(theme=light) %}"
data-theme="{% raw(theme=book) %}"
data-lang="{% raw(lang=en) %}"
data-loading="{% raw(loading=lazy) %}"
crossorigin="anonymous"
async
></script>
<script>
(() => {
const giscusScript = document.querySelector("script[data-repo][data-repo-id]");
if (giscusScript?.getAttribute("data-theme") !== "book") return;
const mapTheme = (theme) => (theme === "light" || theme === "rust" ? "light" : "dark");
const bookTheme = localStorage.getItem("mdbook-theme") || html.getAttribute("class");
giscusScript.setAttribute("data-theme", mapTheme(bookTheme));
document.querySelectorAll("button[role='menuitem'].theme").forEach((btn) => {
btn.addEventListener("click", (event) => {
theme = mapTheme(event.target.id);
const iframe = document.querySelector("iframe.giscus-frame");
if (iframe) iframe.contentWindow.postMessage({ giscus: { setConfig: { theme } } }, "*");
});
});
})();
</script>
2 changes: 0 additions & 2 deletions templates/scroll-to-top.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@
}
}
</style>

<button type="button" aria-label="scroll-to-top" class="scroll-to-top hidden" onclick="scrollToTop()">
<i class="fa fa-angle-up"></i>
</button>

<script>
const scrollToTop = () => window.scroll({ top: 0, behavior: "smooth" });
window.addEventListener("scroll", () => {
Expand Down

0 comments on commit 23eb4e3

Please sign in to comment.