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

fix: CodeBlock fixes (select menu, bundled languages, paste from VS Code) #1219

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 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
26 changes: 18 additions & 8 deletions packages/core/src/blocks/CodeBlockContent/CodeBlockContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,15 @@ const CodeBlockContent = createStronglyTypedTiptapNode({
};
},
addAttributes() {
const supportedLanguages = this.options
.supportedLanguages as SupportedLanguageConfig[];

return {
language: {
default: this.options.defaultLanguage,
parseHTML: (inputElement) => {
let element = inputElement as HTMLElement | null;
let language: string | null = null;

if (
element?.tagName === "DIV" &&
Expand All @@ -67,20 +71,26 @@ const CodeBlockContent = createStronglyTypedTiptapNode({
const dataLanguage = element?.getAttribute("data-language");

if (dataLanguage) {
return dataLanguage.toLowerCase();
language = dataLanguage.toLowerCase();
} else {
const classNames = [...(element?.className.split(" ") || [])];
const languages = classNames
.filter((className) => className.startsWith("language-"))
.map((className) => className.replace("language-", ""));
const [classLanguage] = languages;

language = classLanguage.toLowerCase();
}

const classNames = [...(element?.className.split(" ") || [])];
const languages = classNames
.filter((className) => className.startsWith("language-"))
.map((className) => className.replace("language-", ""));
const [language] = languages;

if (!language) {
return null;
}

return language.toLowerCase();
return (
supportedLanguages.find(({ match }) => {
return match.includes(language);
})?.id || this.options.defaultLanguage
);
},
renderHTML: (attributes) => {
return attributes.language && attributes.language !== "text"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bundledLanguagesInfo } from "shiki/bundle/web";
import { bundledLanguagesInfo } from "shiki";

Copy link
Collaborator

Choose a reason for hiding this comment

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

@areknawo if we're selecting 1 bundle, doesn't it make more sense to only use "shiki/bundle/web"; to bring down size at least a little?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@YousefED Not sure if it'd work. bundledLanguagesInfo is used to verify if specific language ID can be loaded. If it was limited to languages from the web bundle, languages outside of it wouldn't work.

Apart from the check, it might also affect bundling. Importing the full package, all languages are included in the bundle and you can customize which one you choose to support (and externalize others from the bundle). If it was limited to the web bundle, I'm not sure if other language would work at all.

Copy link
Collaborator

@YousefED YousefED Nov 18, 2024

Choose a reason for hiding this comment

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

If we're fine with only supporting languages from the web bundle we can limit to shiki/bundle/web right? I think that's ok for now until we get requests for more esoteric languages.,

Also, I'm thinking we might want to shift to forcing users to pass in languages explicitly; while that would not disable syntax highlighting by default, I think it's also important to have a cleaner packaging / bundling experience

Copy link
Contributor Author

@areknawo areknawo Nov 18, 2024

Choose a reason for hiding this comment

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

In that case - yes. Worth noting though that the current defaults include a few languages outside the web bundle.

As for the latter - I agree that switching to explicit imports would make sense. The only drawback would be more difficult customization and a question of balance between built-in defaults and languages you have to import (in that case, maybe it makes sense to remove the defaults completely?)

export type SupportedLanguageConfig = {
id: string;
Expand All @@ -14,30 +14,50 @@ export const defaultSupportedLanguages: SupportedLanguageConfig[] = [
},
...bundledLanguagesInfo
.filter((lang) => {
return ![
"angular-html",
"angular-ts",
"astro",
"blade",
"coffee",
"handlebars",
"html-derivative",
"http",
"imba",
"jinja",
"jison",
"json5",
"marko",
"mdc",
"stylus",
"ts-tags",
return [
"c",
"cpp",
"css",
"glsl",
"graphql",
"haml",
"html",
"java",
"javascript",
"json",
"jsonc",
"jsonl",
"jsx",
"julia",
"less",
"markdown",
"mdx",
"php",
"postcss",
"pug",
"python",
"r",
"regexp",
"sass",
"scss",
"shellscript",
"sql",
"svelte",
"typescript",
"vue",
"vue-html",
"wasm",
"wgsl",
"xml",
"yaml",
].includes(lang.id);
})
.map((lang) => ({
match: [lang.id, ...(lang.aliases || [])],
id: lang.id,
name: lang.name,
})),
{ id: "tsx", name: "TSX", match: ["tsx", "typescriptreact"] },
{
id: "haskell",
name: "Haskell",
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/editor/Block.css
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ NESTED BLOCKS
transition: opacity 0.3s;
transition-delay: 1s;
}
.bn-block-content[data-content-type="codeBlock"] > div > select > option {
color: black;
}
.bn-block-content[data-content-type="codeBlock"]:hover > div > select,
.bn-block-content[data-content-type="codeBlock"] > div > select:focus {
opacity: 0.5;
Expand Down
Loading