mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-25 05:41:13 +00:00
Revert "Improve handling/escaping of a few possible html entities for posts titles (&) - does not fix backend, only frontend display (#2087)"
This reverts commit 8977b5353a
.
This commit is contained in:
parent
8660a788bf
commit
f4172b42b8
5 changed files with 18 additions and 92 deletions
|
@ -1,7 +1,6 @@
|
||||||
import { Component } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { Post } from "lemmy-js-client";
|
import { Post } from "lemmy-js-client";
|
||||||
import * as sanitizeHtml from "sanitize-html";
|
import * as sanitizeHtml from "sanitize-html";
|
||||||
import { unescapeHTML } from "@utils/helpers";
|
|
||||||
import { relTags } from "../../config";
|
import { relTags } from "../../config";
|
||||||
import { Icon } from "../common/icon";
|
import { Icon } from "../common/icon";
|
||||||
|
|
||||||
|
@ -26,21 +25,17 @@ export class MetadataCard extends Component<MetadataCardProps> {
|
||||||
{post.name !== post.embed_title && (
|
{post.name !== post.embed_title && (
|
||||||
<>
|
<>
|
||||||
<h5 className="card-title d-inline">
|
<h5 className="card-title d-inline">
|
||||||
<a
|
<a className="text-body" href={post.url} rel={relTags}>
|
||||||
className="text-body"
|
{post.embed_title}
|
||||||
href={unescapeHTML(post.url)}
|
|
||||||
rel={relTags}
|
|
||||||
>
|
|
||||||
{unescapeHTML(post.embed_title)}
|
|
||||||
</a>
|
</a>
|
||||||
</h5>
|
</h5>
|
||||||
<span className="d-inline-block ms-2 mb-2 small text-muted">
|
<span className="d-inline-block ms-2 mb-2 small text-muted">
|
||||||
<a
|
<a
|
||||||
className="text-muted fst-italic"
|
className="text-muted fst-italic"
|
||||||
href={unescapeHTML(post.url)}
|
href={post.url}
|
||||||
rel={relTags}
|
rel={relTags}
|
||||||
>
|
>
|
||||||
{new URL(unescapeHTML(post.url)).hostname}
|
{new URL(post.url).hostname}
|
||||||
<Icon icon="external-link" classes="ms-1" />
|
<Icon icon="external-link" classes="ms-1" />
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {
|
||||||
capitalizeFirstLetter,
|
capitalizeFirstLetter,
|
||||||
futureDaysToUnixTime,
|
futureDaysToUnixTime,
|
||||||
hostname,
|
hostname,
|
||||||
unescapeHTML,
|
|
||||||
} from "@utils/helpers";
|
} from "@utils/helpers";
|
||||||
import { isImage, isVideo } from "@utils/media";
|
import { isImage, isVideo } from "@utils/media";
|
||||||
import {
|
import {
|
||||||
|
@ -207,9 +206,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<>
|
<>
|
||||||
{this.listing()}
|
{this.listing()}
|
||||||
{this.state.imageExpanded && !this.props.hideImage && this.img}
|
{this.state.imageExpanded && !this.props.hideImage && this.img}
|
||||||
{this.showBody &&
|
{this.showBody && post.url && post.embed_title && (
|
||||||
unescapeHTML(post.url) &&
|
<MetadataCard post={post} />
|
||||||
unescapeHTML(post.embed_title) && <MetadataCard post={post} />}
|
)}
|
||||||
{this.showBody && this.body()}
|
{this.showBody && this.body()}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
@ -286,8 +285,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<iframe
|
<iframe
|
||||||
allowFullScreen
|
allowFullScreen
|
||||||
className="post-metadata-iframe"
|
className="post-metadata-iframe"
|
||||||
src={unescapeHTML(post.embed_video_url)}
|
src={post.embed_video_url}
|
||||||
title={unescapeHTML(post.embed_title)}
|
title={post.embed_title}
|
||||||
></iframe>
|
></iframe>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -310,7 +309,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
|
|
||||||
get imageSrc(): string | undefined {
|
get imageSrc(): string | undefined {
|
||||||
const post = this.postView.post;
|
const post = this.postView.post;
|
||||||
const url = unescapeHTML(post.url);
|
const url = post.url;
|
||||||
const thumbnail = post.thumbnail_url;
|
const thumbnail = post.thumbnail_url;
|
||||||
|
|
||||||
if (thumbnail) {
|
if (thumbnail) {
|
||||||
|
@ -324,7 +323,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
|
|
||||||
thumbnail() {
|
thumbnail() {
|
||||||
const post = this.postView.post;
|
const post = this.postView.post;
|
||||||
const url = unescapeHTML(post.url);
|
const url = post.url;
|
||||||
const thumbnail = post.thumbnail_url;
|
const thumbnail = post.thumbnail_url;
|
||||||
|
|
||||||
if (!this.props.hideImage && url && isImage(url) && this.imageSrc) {
|
if (!this.props.hideImage && url && isImage(url) && this.imageSrc) {
|
||||||
|
@ -450,7 +449,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="d-inline"
|
className="d-inline"
|
||||||
dangerouslySetInnerHTML={mdToHtmlInline(unescapeHTML(post.name))}
|
dangerouslySetInnerHTML={mdToHtmlInline(post.name)}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
@ -458,7 +457,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
|
|
||||||
postTitleLine() {
|
postTitleLine() {
|
||||||
const post = this.postView.post;
|
const post = this.postView.post;
|
||||||
const url = unescapeHTML(post.url);
|
const url = post.url;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -474,9 +473,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
href={url}
|
href={url}
|
||||||
title={url}
|
title={url}
|
||||||
rel={relTags}
|
rel={relTags}
|
||||||
dangerouslySetInnerHTML={mdToHtmlInline(
|
dangerouslySetInnerHTML={mdToHtmlInline(post.name)}
|
||||||
unescapeHTML(post.name),
|
|
||||||
)}
|
|
||||||
></a>
|
></a>
|
||||||
) : (
|
) : (
|
||||||
this.postLink
|
this.postLink
|
||||||
|
@ -489,7 +486,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
* MetadataCard/body toggle.
|
* MetadataCard/body toggle.
|
||||||
*/}
|
*/}
|
||||||
{!this.props.showBody &&
|
{!this.props.showBody &&
|
||||||
(unescapeHTML(post.url && post.embed_title) || post.body) &&
|
((post.url && post.embed_title) || post.body) &&
|
||||||
this.showPreviewButton()}
|
this.showPreviewButton()}
|
||||||
|
|
||||||
{post.removed && (
|
{post.removed && (
|
||||||
|
@ -551,7 +548,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
|
|
||||||
urlLine() {
|
urlLine() {
|
||||||
const post = this.postView.post;
|
const post = this.postView.post;
|
||||||
const url = unescapeHTML(post.url);
|
const url = post.url;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p className="small m-0">
|
<p className="small m-0">
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {
|
||||||
restoreScrollPosition,
|
restoreScrollPosition,
|
||||||
saveScrollPosition,
|
saveScrollPosition,
|
||||||
} from "@utils/browser";
|
} from "@utils/browser";
|
||||||
import { debounce, randomStr, unescapeHTML } from "@utils/helpers";
|
import { debounce, randomStr } from "@utils/helpers";
|
||||||
import { isImage } from "@utils/media";
|
import { isImage } from "@utils/media";
|
||||||
import { RouteDataResponse } from "@utils/types";
|
import { RouteDataResponse } from "@utils/types";
|
||||||
import autosize from "autosize";
|
import autosize from "autosize";
|
||||||
|
@ -325,9 +325,8 @@ export class Post extends Component<any, PostState> {
|
||||||
|
|
||||||
get documentTitle(): string {
|
get documentTitle(): string {
|
||||||
const siteName = this.state.siteRes.site_view.site.name;
|
const siteName = this.state.siteRes.site_view.site.name;
|
||||||
const postTitle = unescapeHTML(this.state.postRes.data.post_view.post.name);
|
|
||||||
return this.state.postRes.state === "success"
|
return this.state.postRes.state === "success"
|
||||||
? `${postTitle} - ${siteName}`
|
? `${this.state.postRes.data.post_view.post.name} - ${siteName}`
|
||||||
: siteName;
|
: siteName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
const matchEscHtmlRx = /["'&<>]/;
|
|
||||||
const matchUnEscRx = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
|
|
||||||
|
|
||||||
export function escapeHTML(str: string): string {
|
|
||||||
const matchEscHtml = matchEscHtmlRx.exec(str);
|
|
||||||
if (!matchEscHtml) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
let escape;
|
|
||||||
let html = "";
|
|
||||||
let index = 0;
|
|
||||||
let lastIndex = 0;
|
|
||||||
for (index = matchEscHtml.index; index < str.length; index++) {
|
|
||||||
switch (str.charCodeAt(index)) {
|
|
||||||
case 34: // "
|
|
||||||
escape = """;
|
|
||||||
break;
|
|
||||||
case 38: // &
|
|
||||||
escape = "&";
|
|
||||||
break;
|
|
||||||
case 39: // '
|
|
||||||
escape = "'";
|
|
||||||
break;
|
|
||||||
case 60: // <
|
|
||||||
escape = "<";
|
|
||||||
break;
|
|
||||||
case 62: // >
|
|
||||||
escape = ">";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastIndex !== index) {
|
|
||||||
html += str.substring(lastIndex, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastIndex = index + 1;
|
|
||||||
html += escape;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function unescapeHTML(str: string): string {
|
|
||||||
const matchUnEsc = matchUnEscRx.exec(str);
|
|
||||||
if (!matchUnEsc) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = str
|
|
||||||
.replace(/"/g, '"')
|
|
||||||
.replace(/'/g, "'")
|
|
||||||
.replace(/:/g, ":")
|
|
||||||
.replace(/</g, "<")
|
|
||||||
.replace(/>/g, ">")
|
|
||||||
.replace(/&/g, "&");
|
|
||||||
|
|
||||||
return unescapeHTML(res);
|
|
||||||
}
|
|
|
@ -18,19 +18,16 @@ import numToSI from "./num-to-si";
|
||||||
import poll from "./poll";
|
import poll from "./poll";
|
||||||
import randomStr from "./random-str";
|
import randomStr from "./random-str";
|
||||||
import removeAuthParam from "./remove-auth-param";
|
import removeAuthParam from "./remove-auth-param";
|
||||||
import returnStringFromString from "./return-str";
|
|
||||||
import sleep from "./sleep";
|
import sleep from "./sleep";
|
||||||
import validEmail from "./valid-email";
|
import validEmail from "./valid-email";
|
||||||
import validInstanceTLD from "./valid-instance-tld";
|
import validInstanceTLD from "./valid-instance-tld";
|
||||||
import validTitle from "./valid-title";
|
import validTitle from "./valid-title";
|
||||||
import validURL from "./valid-url";
|
import validURL from "./valid-url";
|
||||||
import { escapeHTML, unescapeHTML } from "./html-entities";
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
capitalizeFirstLetter,
|
capitalizeFirstLetter,
|
||||||
debounce,
|
debounce,
|
||||||
editListImmutable,
|
editListImmutable,
|
||||||
escapeHTML,
|
|
||||||
formatPastDate,
|
formatPastDate,
|
||||||
futureDaysToUnixTime,
|
futureDaysToUnixTime,
|
||||||
getIdFromString,
|
getIdFromString,
|
||||||
|
@ -48,9 +45,7 @@ export {
|
||||||
poll,
|
poll,
|
||||||
randomStr,
|
randomStr,
|
||||||
removeAuthParam,
|
removeAuthParam,
|
||||||
returnStringFromString,
|
|
||||||
sleep,
|
sleep,
|
||||||
unescapeHTML,
|
|
||||||
validEmail,
|
validEmail,
|
||||||
validInstanceTLD,
|
validInstanceTLD,
|
||||||
validTitle,
|
validTitle,
|
||||||
|
|
Loading…
Reference in a new issue