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

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

Open
progmars opened this issue Dec 11, 2024 · 1 comment

Comments

@progmars
Copy link

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;
};
</script>

<template>
  <input type="button" @click="doHighlight()" value="Do highlight!" style="border: 1px solid red;"/>
  <pre><code class="language-javascript" id="scripted-highlight">els 'something</code></pre>
  <pre><code id="manual-highlight"></code></pre>
  <highlightjs language="javascript" code="els 'something"></highlightjs>

Here's what I see after clicking the button:

image

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;
};
</script>

<template>
  <input type="button" @click="doHighlight()" value="Do highlight!" style="border: 1px solid red;"/>
  <pre><code class="language-javascript" id="scripted-highlight">else 'something</code></pre>
  <pre><code id="manual-highlight"></code></pre>
  <highlightjs language="javascript" code="else 'something"></highlightjs>

Now the highlightjs also got something colored, as expected!

image

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

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.

@joshgoebel
Copy link
Member

I think the language choice is somehow broken with the plugin, just a guess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants