highlightjs / highlightjs/vue-plugin

The plugin behaves differently from highlight.js - it does not detect an opening token if it comes as the very first higlightable token

Open
#53 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
241
Forks
29
PR merge metrics
No merged PRs in 30d

Description

Not sure if the title makes sense. Essentially, the behavior of this plugin differs from the behavior of raw highlight.js.

To reproduce the issue, I have the following relevant pieces of code in my Vue app setup:
```
import { createApp } from "vue";
import App from "./App.vue";

import "highlight.js/styles/stackoverflow-light.css";
import javascript from "highlight.js/lib/languages/javascript";

import hljs from "highlight.js/lib/core";
import hljsVuePlugin from "@highlightjs/vue-plugin";

hljs.registerLanguage("javascript", javascript);

createApp(App).use(hljsVuePlugin).mount("#app");
```

My test template:

```
const doHighlight = () => {
hljs.highlightElement(document.getElementById("scripted-highlight"));
const result = hljs.highlight("els 'something", { language: "javascript" });
document.getElementById("manual-highlight").innerHTML = result.value;
};


els 'something


```

Here's what I see after clicking the button:

![image](https://github.com/user-attachments/assets/681ee4cb-e602-488b-9697-2b9723ab9fc2)

Ignore the background, pay attention to the color of `something`. It is highlighted only inside the HTML elements that use the raw hljs API, but not in the Vue `highlightjs` element.

Now I change `els` to `else` so that the quoted string has a keyword before it:

```
const doHighlight = () => {
hljs.highlightElement(document.getElementById("scripted-highlight"));
const result = hljs.highlight("else 'something", { language: "javascript" });
document.getElementById("manual-highlight").innerHTML = result.value;
};


else 'something


```

Now the `highlightjs` also got `something` colored, as expected!

![image](https://github.com/user-attachments/assets/3c177322-4405-4cd1-beed-3cf279d340e3)

This leads to the situation when the user gets colored output only if they do not start typing with something that does not have a start token (such as a quote).

When I check the generated code for the broken case with `els 'something`, it shows that hljs class had been assigned to the `code` element, but there is no `span` element:
![image](https://github.com/user-attachments/assets/faea51f7-4ad0-493a-8fe6-40b96fc8c00d)

I'm puzzled, what's going on there? The Vue plugin should not affect the parsing of the tokens; it's just a wrapper around hljs , isn't it?

I guess, I'll have to use the raw hljs API instead of the Vue plugin unless somebody has a clue how to fix this easily.

_The long story. I have built a real-time editor with highlighting for my project to have custom token parsing and noticed that when I type an opening token, the token and the following text are not highlighted until I add the closing token. For example, I start typing `'something` and it is not colored until I type the closing quote, e.g. `'something'`. But then I discovered that if I type a keyword, such as `else` in front of the opening quote, then suddenly the coloring works from the start. I was pulling my hair, trying to understand what was wrong with my custom language setup.
Then I switched to Javascript highlighting, and it had the same issue. Then I went to the highlight.js demo website and checked it there - no problems! Then I added raw HTML and hljs API calls to my code - and it also worked fine. So I concluded that there is some kind of black magic happening with that vue plugin and I'm missing something or it's a bug._

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.