Fix css conflicts on diff syntaxhighlighting by using a css module

This commit is contained in:
Sebastian Sdorra
2020-10-23 13:06:36 +02:00
parent ea1eab6356
commit 5f30cf8f30
10 changed files with 156 additions and 113 deletions

View File

@@ -24,14 +24,28 @@
// @ts-ignore we have no types for react-diff-view
import { tokenize } from "react-diff-view";
import refractor from "./refractorAdapter";
import createRefractor, { RefractorAdapter } from "./refractorAdapter";
// the WorkerGlobalScope is assigned to self
// see https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/self
declare const self: Worker;
self.addEventListener("message", ({ data: { id, payload } }) => {
type TokenizeMessage = {
id: string;
language: string;
hunks: any;
payload: any;
};
let refractor: RefractorAdapter;
function initRefractor(theme: { [key: string]: string }) {
refractor = createRefractor(theme);
}
function runTokenize({ id, payload }: TokenizeMessage) {
const { hunks, language } = payload;
const options = {
highlight: language !== "text",
language: language,
@@ -60,4 +74,12 @@ self.addEventListener("message", ({ data: { id, payload } }) => {
if (options.highlight) {
refractor.loadLanguage(language, createTokenizer(self));
}
}
self.addEventListener("message", ({ data }) => {
if (data.theme) {
initRefractor(data.theme);
} else {
runTokenize(data);
}
});

View File

@@ -28,10 +28,8 @@ import { Diff, useTokenizeWorker } from "react-diff-view";
import { File } from "./DiffTypes";
import { determineLanguage } from "../languages";
// styling for the diff tokens
// this must be aligned with th style, which is used in the SyntaxHighlighter component
// eslint-disable-next-line no-restricted-imports
import "../syntax-highlighting.css";
// @ts-ignore no types for css modules
import theme from "../syntax-highlighting.module.css";
const DiffView = styled(Diff)`
/* align line numbers */
@@ -60,26 +58,11 @@ const DiffView = styled(Diff)`
&.unified .diff-widget-content .is-indented-line {
padding-left: 6.5rem;
}
/* conflict between prism and bulma number class */
.number {
align-items: inherit;
background-color: inherit;
border-radius: inherit;
display: initial;
font-size: inherit;
height: inherit;
justify-content: inherit;
margin-right: inherit;
margin-left: 0;
min-width: inherit;
padding: 0;
text-align: inherit;
}
`;
// WebWorker which creates tokens for syntax highlighting
const tokenize = new Worker("./Tokenize.worker.ts", { name: "tokenizer", type: "module" });
tokenize.postMessage({ theme });
type Props = {
file: File;

View File

@@ -24,29 +24,51 @@
import refractor from "refractor/core";
const isLanguageRegistered = (lang: string) => {
const registeredLanguages = refractor.listLanguages();
return registeredLanguages.includes(lang);
type RunHookEnv = {
classes: string[];
};
const loadLanguage = (lang: string, callback: () => void) => {
if (isLanguageRegistered(lang)) {
callback();
} else {
import(
/* webpackChunkName: "tokenizer-refractor-[request]" */
`refractor/lang/${lang}`
).then(loadedLanguage => {
refractor.register(loadedLanguage.default);
export type RefractorAdapter = typeof refractor & {
isLanguageRegistered: (lang: string) => boolean;
loadLanguage: (lang: string, callback: () => void) => void;
};
const createAdapter = (theme: { [key: string]: string }): RefractorAdapter => {
const isLanguageRegistered = (lang: string) => {
const registeredLanguages = refractor.listLanguages();
return registeredLanguages.includes(lang);
};
const loadLanguage = (lang: string, callback: () => void) => {
if (isLanguageRegistered(lang)) {
callback();
});
}
} else {
import(
/* webpackChunkName: "tokenizer-refractor-[request]" */
`refractor/lang/${lang}`
).then(loadedLanguage => {
refractor.register(loadedLanguage.default);
callback();
});
}
};
// @ts-ignore hooks are not in the type definition
const originalRunHook = refractor.hooks.run;
const runHook = (name: string, env: RunHookEnv) => {
originalRunHook.apply(name, env);
if (env.classes) {
env.classes = env.classes.map(className => theme[className] || className);
}
};
// @ts-ignore hooks are not in the type definition
refractor.hooks.run = runHook;
return {
isLanguageRegistered,
loadLanguage,
...refractor
};
};
const refractorAdapter = {
isLanguageRegistered,
loadLanguage,
...refractor
};
export default refractorAdapter;
export default createAdapter;