.styling. dom purify just to be sure.

This commit is contained in:
Jason Schwarzenberger 2020-12-02 13:03:16 +13:00
parent 7f46646b9a
commit 32f1455bbb
7 changed files with 68 additions and 37 deletions

View File

@ -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",

View File

@ -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>

View File

@ -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}

View File

@ -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}&larr; 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>

View File

@ -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}&bull; {story.score} points{/if} {#if story.score}&bull; {story.score} points{/if}
{#if story.num_comments} {#if story.num_comments}
&bull; &bull;

View File

@ -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;
}

View File

@ -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"