.styling. dom purify just to be sure.
This commit is contained in:
parent
7f46646b9a
commit
32f1455bbb
|
@ -11,6 +11,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"compression": "^1.7.1",
|
"compression": "^1.7.1",
|
||||||
"date-fns": "^2.16.1",
|
"date-fns": "^2.16.1",
|
||||||
|
"dompurify": "^2.2.2",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
|
|
|
@ -1,13 +1,41 @@
|
||||||
<script>
|
<script>
|
||||||
|
import DOMPurify from "dompurify";
|
||||||
|
import { onMount } from "svelte";
|
||||||
import StoryInfo from "../components/StoryInfo.svelte";
|
import StoryInfo from "../components/StoryInfo.svelte";
|
||||||
|
|
||||||
export let story;
|
export let story;
|
||||||
|
|
||||||
let host = new URL(story.url || story.link).hostname.replace(/^www\./, "");
|
let host = new URL(story.url || story.link).hostname.replace(/^www\./, "");
|
||||||
|
let html;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
html = DOMPurify.sanitize(story.text);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.article :global(h1),
|
||||||
|
.article :global(h2),
|
||||||
|
.article :global(h3),
|
||||||
|
.article :global(h4),
|
||||||
|
.article :global(h5),
|
||||||
|
.article :global(h6) {
|
||||||
|
margin: 0 0 0.5em 0;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article :global(h1) {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
|
||||||
|
.article :global(h1) {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
.article-title {
|
.article-title {
|
||||||
text-align: justify;
|
text-align: left;
|
||||||
}
|
}
|
||||||
.article-header {
|
.article-header {
|
||||||
padding: 0 0 1rem;
|
padding: 0 0 1rem;
|
||||||
|
@ -41,12 +69,14 @@
|
||||||
<header class="article-header">
|
<header class="article-header">
|
||||||
<h1 class="article-title">{story.title}</h1>
|
<h1 class="article-title">{story.title}</h1>
|
||||||
{#if story.url}
|
{#if story.url}
|
||||||
<div>source: <a href={story.url}>{host}</a></div>
|
<div>source: <a class="article-source" href={story.url}>{host}</a></div>
|
||||||
{/if}
|
{/if}
|
||||||
<StoryInfo class="article-byline" {story} />
|
<section class="article-info">
|
||||||
|
<StoryInfo {story} />
|
||||||
|
</section>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section class="article-body">
|
<section class="article-body">
|
||||||
{@html story.text}
|
{@html html}
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
<script>
|
<script>
|
||||||
|
import DOMPurify from "dompurify";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
import Time from "../components/Time.svelte";
|
import Time from "../components/Time.svelte";
|
||||||
|
|
||||||
export let story;
|
export let story;
|
||||||
export let comment;
|
export let comment;
|
||||||
export let showComments = true;
|
export let showComments = true;
|
||||||
const author = (comment.author || "").replace(" ", "");
|
|
||||||
export let id = `${author}-${comment.date}`;
|
|
||||||
|
|
||||||
export function toggleComments() {
|
let author = (comment.author || "").replace(" ", "");
|
||||||
|
let id = `${author}-${comment.date}`;
|
||||||
|
|
||||||
|
let html;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
html = DOMPurify.sanitize(comment.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggleComments() {
|
||||||
showComments = !showComments;
|
showComments = !showComments;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -87,7 +97,7 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section class={showComments ? 'comment-text' : 'comment-text is-collapsed'}>
|
<section class={showComments ? 'comment-text' : 'comment-text is-collapsed'}>
|
||||||
{@html comment.text}
|
{@html html}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{#if !showComments}
|
{#if !showComments}
|
||||||
|
|
|
@ -28,13 +28,11 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.has-highlight,
|
|
||||||
[aria-current] {
|
[aria-current] {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-highlight::after,
|
|
||||||
[aria-current]::after {
|
[aria-current]::after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "";
|
content: "";
|
||||||
|
@ -72,7 +70,6 @@
|
||||||
.navigation-item {
|
.navigation-item {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
.navigation-text,
|
|
||||||
.navigation-link {
|
.navigation-link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding: 1em 0.5em;
|
padding: 1em 0.5em;
|
||||||
|
@ -82,7 +79,8 @@
|
||||||
line-height: 2;
|
line-height: 2;
|
||||||
margin: 1em;
|
margin: 1em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
width: 15rem;
|
width: 20rem;
|
||||||
|
max-width: 50vw;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -94,7 +92,9 @@
|
||||||
class="navigation-link"
|
class="navigation-link"
|
||||||
aria-current={segment === undefined ? 'page' : undefined}
|
aria-current={segment === undefined ? 'page' : undefined}
|
||||||
rel="prefetch"
|
rel="prefetch"
|
||||||
href=".">News</a>
|
href=".">
|
||||||
|
{#if segment === undefined}Qot.{:else}← News feed{/if}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<form action="/search" method="GET" rel="prefetch" role="search">
|
<form action="/search" method="GET" rel="prefetch" role="search">
|
||||||
|
@ -108,11 +108,5 @@
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
on:keypress={handleSearch} />
|
on:keypress={handleSearch} />
|
||||||
</form>
|
</form>
|
||||||
<ul class="navigation-list">
|
|
||||||
<li class="navigation-item">
|
|
||||||
<span
|
|
||||||
class="navigation-text {segment !== undefined ? 'has-highlight' : undefined}">Qot.</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
<Time date={story.date} />
|
<Time date={story.date} />
|
||||||
{#if story.author && story.author_link}
|
{#if story.author && story.author_link}
|
||||||
by
|
by
|
||||||
<a href={story.author_link}>{story.author}</a>
|
<a class="author" href={story.author_link}>{story.author}</a>
|
||||||
{:else if story.author}by {story.author}{/if}
|
{:else if story.author}by <span class="author">{story.author}</span>{/if}
|
||||||
on
|
on
|
||||||
<a href={story.link || story.url}>{story.source}</a>
|
<a class="source" href={story.link || story.url}>{story.source}</a>
|
||||||
{#if story.score}• {story.score} points{/if}
|
{#if story.score}• {story.score} points{/if}
|
||||||
{#if story.num_comments}
|
{#if story.num_comments}
|
||||||
•
|
•
|
||||||
|
|
|
@ -9,25 +9,11 @@ body {
|
||||||
margin-bottom: 50vh;
|
margin-bottom: 50vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6 {
|
|
||||||
margin: 0 0 0.5em 0;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre,
|
||||||
code {
|
code {
|
||||||
font-family: menlo, inconsolata, monospace;
|
font-family: menlo, inconsolata, monospace;
|
||||||
font-size: calc(1em - 2px);
|
font-size: calc(1em - 2px);
|
||||||
|
@ -36,3 +22,8 @@ code {
|
||||||
padding: 0.2em 0.4em;
|
padding: 0.2em 0.4em;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
|
@ -779,6 +779,11 @@ domain-browser@^1.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||||
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
||||||
|
|
||||||
|
dompurify@^2.2.2:
|
||||||
|
version "2.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.2.tgz#cb8c2b1a2f3c8a0b565127504ae4eedec176a972"
|
||||||
|
integrity sha512-BsGR4nDLaC5CNBnyT5I+d5pOeaoWvgVeg6Gq/aqmKYWMPR07131u60I80BvExLAJ0FQEIBQ1BTicw+C5+jOyrg==
|
||||||
|
|
||||||
duplexify@^3.4.2, duplexify@^3.6.0:
|
duplexify@^3.4.2, duplexify@^3.6.0:
|
||||||
version "3.7.1"
|
version "3.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
|
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user