Fix view source and devtools showing hljs warnings (#7759)

pull/21833/head
Michael Telatynski 2022-02-09 09:09:06 +00:00 committed by GitHub
parent 094b29bb21
commit 2b72a2cc2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 46 deletions

View File

@ -71,13 +71,13 @@ export default class ViewSource extends React.Component<IProps, IState> {
<summary>
<span className="mx_ViewSource_heading">{ _t("Decrypted event source") }</span>
</summary>
<SyntaxHighlight className="json">{ JSON.stringify(decryptedEventSource, null, 2) }</SyntaxHighlight>
<SyntaxHighlight language="json">{ JSON.stringify(decryptedEventSource, null, 2) }</SyntaxHighlight>
</details>
<details className="mx_ViewSource_details">
<summary>
<span className="mx_ViewSource_heading">{ _t("Original event source") }</span>
</summary>
<SyntaxHighlight className="json">{ JSON.stringify(originalEventSource, null, 2) }</SyntaxHighlight>
<SyntaxHighlight language="json">{ JSON.stringify(originalEventSource, null, 2) }</SyntaxHighlight>
</details>
</>
);
@ -85,7 +85,7 @@ export default class ViewSource extends React.Component<IProps, IState> {
return (
<>
<div className="mx_ViewSource_heading">{ _t("Original event source") }</div>
<SyntaxHighlight className="json">{ JSON.stringify(originalEventSource, null, 2) }</SyntaxHighlight>
<SyntaxHighlight language="json">{ JSON.stringify(originalEventSource, null, 2) }</SyntaxHighlight>
</>
);
}

View File

@ -501,7 +501,7 @@ class RoomStateExplorer extends React.PureComponent<IExplorerProps, IRoomStateEx
return <div className="mx_ViewSource">
<div className="mx_Dialog_content">
<SyntaxHighlight className="json">
<SyntaxHighlight language="json">
{ JSON.stringify(this.state.event.event, null, 2) }
</SyntaxHighlight>
</div>
@ -634,7 +634,7 @@ class AccountDataExplorer extends React.PureComponent<IExplorerProps, IAccountDa
return <div className="mx_ViewSource">
<div className="mx_DevTools_content">
<SyntaxHighlight className="json">
<SyntaxHighlight language="json">
{ JSON.stringify(this.state.event.event, null, 2) }
</SyntaxHighlight>
</div>

View File

@ -15,41 +15,26 @@ limitations under the License.
*/
import React from 'react';
import highlight from 'highlight.js';
import hljs from 'highlight.js';
import { replaceableComponent } from "../../../utils/replaceableComponent";
interface IProps {
className?: string;
children?: React.ReactNode;
language?: string;
children: string;
}
@replaceableComponent("views.elements.SyntaxHighlight")
export default class SyntaxHighlight extends React.Component<IProps> {
private el: HTMLPreElement = null;
constructor(props: IProps) {
super(props);
}
// componentDidUpdate used here for reusability
public componentDidUpdate(): void {
if (this.el) highlight.highlightElement(this.el);
}
// call componentDidUpdate because _ref is fired on initial render
// which does not fire componentDidUpdate
private ref = (el: HTMLPreElement): void => {
this.el = el;
this.componentDidUpdate();
};
export default class SyntaxHighlight extends React.PureComponent<IProps> {
public render(): JSX.Element {
const { className, children } = this.props;
const { children: content, language } = this.props;
const highlighted = language ? hljs.highlight(language, content) : hljs.highlightAuto(content);
return <pre className={`${className} mx_SyntaxHighlight`} ref={this.ref}>
<code>{ children }</code>
</pre>;
return (
<pre className={`mx_SyntaxHighlight hljs language-${highlighted.language}`}>
<code dangerouslySetInnerHTML={{ __html: highlighted.value }} />
</pre>
);
}
}

View File

@ -40,6 +40,8 @@ limitations under the License.
// the frequency with which we flush to indexeddb
import { logger } from "matrix-js-sdk/src/logger";
import { getCircularReplacer } from "../utils/JSON";
const FLUSH_RATE_MS = 30 * 1000;
// the length of log data we keep in indexeddb (and include in the reports)
@ -90,21 +92,7 @@ export class ConsoleLogger {
} else if (arg instanceof Error) {
return arg.message + (arg.stack ? `\n${arg.stack}` : '');
} else if (typeof (arg) === 'object') {
try {
return JSON.stringify(arg);
} catch (e) {
// In development, it can be useful to log complex cyclic
// objects to the console for inspection. This is fine for
// the console, but default `stringify` can't handle that.
// We workaround this by using a special replacer function
// to only log values of the root object and avoid cycles.
return JSON.stringify(arg, (key, value) => {
if (key && typeof value === "object") {
return "<object>";
}
return value;
});
}
return JSON.stringify(arg, getCircularReplacer());
} else {
return arg;
}

32
src/utils/JSON.ts Normal file
View File

@ -0,0 +1,32 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
type StringifyReplacer = (this: any, key: string, value: any) => any;
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#circular_references
// Injects `<$ cycle-trimmed $>` wherever it cuts a cyclical object relationship
export const getCircularReplacer = (): StringifyReplacer => {
const seen = new WeakSet();
return (key: string, value: any): any => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return "<$ cycle-trimmed $>";
}
seen.add(value);
}
return value;
};
};