forked from tanner/qotnews
		
	.styling. dom purify just to be sure.
This commit is contained in:
		| @@ -11,6 +11,7 @@ | ||||
|   "dependencies": { | ||||
|     "compression": "^1.7.1", | ||||
|     "date-fns": "^2.16.1", | ||||
|     "dompurify": "^2.2.2", | ||||
|     "isomorphic-fetch": "^3.0.0", | ||||
|     "lodash": "^4.17.20", | ||||
|     "node-fetch": "^2.6.1", | ||||
|   | ||||
| @@ -1,13 +1,41 @@ | ||||
| <script> | ||||
|   import DOMPurify from "dompurify"; | ||||
|   import { onMount } from "svelte"; | ||||
|   import StoryInfo from "../components/StoryInfo.svelte"; | ||||
|  | ||||
|   export let story; | ||||
|  | ||||
|   let host = new URL(story.url || story.link).hostname.replace(/^www\./, ""); | ||||
|   let html; | ||||
|  | ||||
|   onMount(() => { | ||||
|     html = DOMPurify.sanitize(story.text); | ||||
|   }); | ||||
| </script> | ||||
|  | ||||
| <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 { | ||||
|     text-align: justify; | ||||
|     text-align: left; | ||||
|   } | ||||
|   .article-header { | ||||
|     padding: 0 0 1rem; | ||||
| @@ -41,12 +69,14 @@ | ||||
|   <header class="article-header"> | ||||
|     <h1 class="article-title">{story.title}</h1> | ||||
|     {#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} | ||||
|     <StoryInfo class="article-byline" {story} /> | ||||
|     <section class="article-info"> | ||||
|       <StoryInfo {story} /> | ||||
|     </section> | ||||
|   </header> | ||||
|  | ||||
|   <section class="article-body"> | ||||
|     {@html story.text} | ||||
|     {@html html} | ||||
|   </section> | ||||
| </article> | ||||
|   | ||||
| @@ -1,13 +1,23 @@ | ||||
| <script> | ||||
|   import DOMPurify from "dompurify"; | ||||
|   import { onMount } from "svelte"; | ||||
|  | ||||
|   import Time from "../components/Time.svelte"; | ||||
|  | ||||
|   export let story; | ||||
|   export let comment; | ||||
|   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; | ||||
|   } | ||||
| </script> | ||||
| @@ -87,7 +97,7 @@ | ||||
|   </header> | ||||
|  | ||||
|   <section class={showComments ? 'comment-text' : 'comment-text is-collapsed'}> | ||||
|     {@html comment.text} | ||||
|     {@html html} | ||||
|   </section> | ||||
|  | ||||
|   {#if !showComments} | ||||
|   | ||||
| @@ -28,13 +28,11 @@ | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
|   .has-highlight, | ||||
|   [aria-current] { | ||||
|     position: relative; | ||||
|     display: inline-block; | ||||
|   } | ||||
|  | ||||
|   .has-highlight::after, | ||||
|   [aria-current]::after { | ||||
|     position: absolute; | ||||
|     content: ""; | ||||
| @@ -72,7 +70,6 @@ | ||||
|   .navigation-item { | ||||
|     list-style: none; | ||||
|   } | ||||
|   .navigation-text, | ||||
|   .navigation-link { | ||||
|     text-decoration: none; | ||||
|     padding: 1em 0.5em; | ||||
| @@ -82,7 +79,8 @@ | ||||
|     line-height: 2; | ||||
|     margin: 1em; | ||||
|     vertical-align: middle; | ||||
|     width: 15rem; | ||||
|     width: 20rem; | ||||
|     max-width: 50vw; | ||||
|   } | ||||
| </style> | ||||
|  | ||||
| @@ -94,7 +92,9 @@ | ||||
|           class="navigation-link" | ||||
|           aria-current={segment === undefined ? 'page' : undefined} | ||||
|           rel="prefetch" | ||||
|           href=".">News</a> | ||||
|           href="."> | ||||
|           {#if segment === undefined}Qot.{:else}← News feed{/if} | ||||
|         </a> | ||||
|       </li> | ||||
|     </ul> | ||||
|     <form action="/search" method="GET" rel="prefetch" role="search"> | ||||
| @@ -108,11 +108,5 @@ | ||||
|         placeholder="Search..." | ||||
|         on:keypress={handleSearch} /> | ||||
|     </form> | ||||
|     <ul class="navigation-list"> | ||||
|       <li class="navigation-item"> | ||||
|         <span | ||||
|           class="navigation-text {segment !== undefined ? 'has-highlight' : undefined}">Qot.</span> | ||||
|       </li> | ||||
|     </ul> | ||||
|   </div> | ||||
| </nav> | ||||
|   | ||||
| @@ -6,10 +6,10 @@ | ||||
| <Time date={story.date} /> | ||||
| {#if story.author && story.author_link} | ||||
|   by | ||||
|   <a href={story.author_link}>{story.author}</a> | ||||
| {:else if story.author}by {story.author}{/if} | ||||
|   <a class="author" href={story.author_link}>{story.author}</a> | ||||
| {:else if story.author}by <span class="author">{story.author}</span>{/if} | ||||
| 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.num_comments} | ||||
|   • | ||||
|   | ||||
| @@ -9,25 +9,11 @@ body { | ||||
|   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 { | ||||
|   color: inherit; | ||||
| } | ||||
|  | ||||
| pre, | ||||
| code { | ||||
|   font-family: menlo, inconsolata, monospace; | ||||
|   font-size: calc(1em - 2px); | ||||
| @@ -36,3 +22,8 @@ code { | ||||
|   padding: 0.2em 0.4em; | ||||
|   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" | ||||
|   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: | ||||
|   version "3.7.1" | ||||
|   resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user