Rewrite XSL for web browser display

This commit is contained in:
Lucidiot 2023-05-21 13:36:00 +02:00
parent 6817b236d1
commit 6a96d22bbf
Signed by: lucidiot
GPG Key ID: 3358C1CA6906FB8D
4 changed files with 270 additions and 96 deletions

View File

@ -1,32 +1,158 @@
body {
background-color: lightgray;
max-width: 640px;
margin: 10px auto;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
h2 {
font-size: 14pt;
}
a {
color: #1264a8;
}
a:visited {
color: #12324c;
}
body > header, body > footer {
background-color: #333;
background: #333 linear-gradient(0, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 100%);
color: white;
padding: 5px;
border: 1px solid white;
border-radius: 5px;
}
body > header {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
min-height: 144px;
}
body > header > h1 {
margin-bottom: 0;
}
body > header > h1 + p {
margin-top: 0;
}
body > header a, body > footer a, body > header a:visited, body > footer a:visited {
color: white;
}
.channel-logo {
float: left;
max-width: 144px;
max-height: 144px;
margin-right: 10px;
}
body > footer {
border-top-right-radius: 0;
border-top-left-radius: 0;
font-size: 8pt;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
body > footer > * {
margin: 0 5px;
}
article {
clear: both;
background-color: whitesmoke;
border-radius: 5px;
padding: 3px 10px 5px;
margin-bottom: 1em;
border: 1px solid gray;
box-shadow: 0 5px 3px -3px #333;
margin: 7px 0;
padding: 5px;
font-size: 10pt;
}
.timestamp {
font-style: italic;
}
.category {
display: inline-block;
padding: 2px 4px;
background-color: lightgray;
border-radius: 3px;
article:first-child {
margin-top: 5px;
}
a {
color: chocolate;
}
a:visited {
color: brown;
article header, article footer {
color: #333;
font-size: 8pt;
}
.buttons > *:not(:last-child) {
margin-right: 0.5em;
article header {
border-bottom: 1px solid lightgray;
padding-bottom: 2px;
margin-bottom: 5px;
}
article footer {
border-top: 1px solid lightgray;
margin-top: 5px;
padding-top: 1px;
}
article header h2, article header p, article footer p {
margin-top: 0;
margin-bottom: 0;
}
article header p *:not(:last-child) {
border-right: 1px solid gray;
padding-right: 0.25em;
margin-right: 0.25em;
}
article a.permalink {
float: right;
}
article blockquote {
margin-left: 0.5em;
border-left: 2px solid lightgray;
padding-left: 0.5em;
}
article figure {
margin-left: 1em;
}
article figure img {
display: block;
margin-left: auto;
margin-right: auto;
}
article table {
width: 100%;
overflow-x: scroll;
}
article pre {
border: 1px dotted gray;
max-width: 100%;
overflow-x: scroll;
}
article ul, article ol {
margin-left: 1em;
padding-left: 0;
}
article dt {
font-weight: bold;
}
article dd {
margin-left: 0.5em;
border-left: 1px dotted gray;
padding-left: 0.5em;
}

View File

@ -16,7 +16,7 @@
<channel>
<title>RSRSSS</title>
<link>https://envs.net/~lucidiot/rsrsss/feed.xml</link>
<description>Really Simple Really Simple Syndication Syndication &#8212; An RSS feed about RSS feeds</description>
<description>Really Simple Really Simple Syndication Syndication &#8212; An&#160;RSS&#160;feed about RSS&#160;feeds</description>
<language>en</language>
<copyright>Creative Commons BY-SA 4.0 International, ~lucidiot</copyright>
<managingEditor>lucidiot@envs.net (lucidiot)</managingEditor>
@ -907,7 +907,7 @@
<p>TinyTinyRSS currently shows that I have 202 feeds. Two of those feeds are currently down, and probably permanently, so I can say I just have 200 feeds.</p>
<p>I mentioned reaching 200 feeds on IRC, and ~dozens awarded me a badge for my <em>outstanding feedchievement</em>!</p>
<figure>
<img src="https://envs.net/~lucidiot/rsrsss/img/200feeds-badge.png" alt="drawing of a coat of arms with 200 written on it, surrounded by the words 'outstanding feedchievement', with a scroll in the background." />
<img src="https://envs.net/~lucidiot/rsrsss/img/200feeds-badge.png" alt="drawing of a coat of arms with 200 written on it, surrounded by the words 'outstanding feedchievement', with a scroll in the background." loading="lazy" />
</figure>
<p>I have quite the backlog of feeds to share on here. Feel free to harass me if I don't post one each week, because I have no excuse.</p>
]]></description>

19
js/script.js Normal file
View File

@ -0,0 +1,19 @@
function hasElementNodes (parent) {
for (var childNodes = parent.childNodes, i = childNodes.length; i--; ) {
if (childNodes[i].nodeType == 1) return true;
}
return false;
}
window.addEventListener('load', function () {
var escaped = document.getElementsByClassName('unescape');
for (var i = 0; i < escaped.length; i++) {
if (hasElementNodes(escaped[i])) return;
}
var textarea = document.createElement('textarea');
for (var i = escaped.length - 1; i >= 0; i--) {
textarea.innerHTML = escaped[i].innerHTML;
escaped[i].outerHTML = textarea.value;
}
textarea.innerHTML = '';
});

View File

@ -2,6 +2,7 @@
<xsl:stylesheet
version="1.0"
xmlns:admin="http://webns.net/mvcb/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:blogChannel="http://backend.userland.com/blogChannelModule"
xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
@ -14,25 +15,37 @@
<title><xsl:value-of select="/rss/channel/title" /></title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<!-- TODO: meta generator -->
<xsl:if test="/rss/channel/atom:link[@rel='self']/@href">
<link rel="alternate" type="application/rss+xml" href="{/rss/channel/atom:link[@rel='self']/@href}" />
</xsl:if>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<xsl:apply-templates />
<body id="top">
<xsl:apply-templates select="/rss/channel" />
</body>
</html>
</xsl:template>
<xsl:template match="channel">
<a href="{image/link/text()}" target="_blank" style="float: right">
<img src="{image/url/text()}" alt="{image/title/text()}" title="{image/description/text()}" />
</a>
<h1><xsl:value-of select="title" /></h1>
<p><xsl:value-of select="description" /></p>
<xsl:apply-templates select="item" />
<p class="buttons">
<!-- TODO: support accent color -->
<header>
<xsl:if test="image">
<a href="{image/link/text()}" class="channel-logo" target="_blank">
<img src="{image/url/text()}" alt="{image/title/text()}" title="{image/description/text()}" />
</a>
</xsl:if>
<h1><xsl:value-of select="title" /></h1>
<p><xsl:value-of select="description" /></p>
</header>
<!-- TODO: <details> to show more info about the feed -->
<main>
<xsl:apply-templates select="item" />
</main>
<footer>
<a href="https://validator.w3.org/feed/check.cgi?url={link/text()}" target="_blank">
<img src="img/valid-rss.png" alt="Valid RSS" />
</a>
<xsl:if test="creativeCommons:license">
<a href="{creativeCommons:license/text()}" target="_blank">
<img
@ -41,36 +54,26 @@
/>
</a>
</xsl:if>
<a href="https://validator.w3.org/feed/check.cgi?url={link/text()}" target="_blank">
<img src="img/valid-rss.png" alt="Valid RSS" />
</a>
</p>
<xsl:if test="admin:errorReportsTo or blogChannel:blogRoll or blogChannel:mySubscriptions or blogChannel:blink">
<p>
<xsl:if test="admin:errorReportsTo">
<a href="{admin:errorReportsTo/@rdf:resource}">Report errors with this feed</a>
</xsl:if>
<xsl:if test="blogChannel:blogRoll">
<xsl:if test="admin:errorReportsTo">
</xsl:if>
<a href="{blogChannel:blogRoll}" target="_blank">Blogroll (OPML)</a>
</xsl:if>
<xsl:if test="blogChannel:mySubscriptions">
<xsl:if test="admin:errorReportsTo or blogChannel:blogRoll">
</xsl:if>
<a href="{blogChannel:mySubscriptions}" target="_blank">Author's subscriptions (OPML)</a>
<xsl:if test="blogChannel:blink">
</xsl:if>
</xsl:if>
<xsl:if test="blogChannel:blink">
<xsl:if test="admin:errorReportsTo">
<a href="{admin:errorReportsTo/@rdf:resource}">Report a bug</a>
</xsl:if>
<xsl:if test="blogChannel:blogRoll">
<a href="{blogChannel:blogRoll}" target="_blank">Blogroll (OPML)</a>
</xsl:if>
<xsl:if test="blogChannel:mySubscriptions">
<a href="{blogChannel:mySubscriptions}" target="_blank">Author's subscriptions (OPML)</a>
</xsl:if>
<xsl:if test="blogChannel:blink">
<span>
<a href="{blogChannel:blink}" target="_blank">B-Link</a>
</xsl:if>
</p>
</xsl:if>
<xsl:text> (</xsl:text>
<a href="http://web.archive.org/web/20020925030017/http://diveintomark.org/archives/2002/09/17.html#blink_and_youll_miss_it" target="_blank">What's this?</a>
<xsl:text>)</xsl:text>
</span>
</xsl:if>
<a href="#top">Back to top</a>
</footer>
<script type="text/javascript" language="javascript" src="js/script.js" />
</xsl:template>
<xsl:template match="item">
@ -81,47 +84,73 @@
</xsl:attribute>
</xsl:if>
<xsl:if test="title">
<h2><xsl:value-of select="title" /></h2>
</xsl:if>
<xsl:if test="guid or pubDate or link or category">
<p>
<xsl:if test="guid">
<a>
<xsl:attribute name="href">
<xsl:if test="guid[@isPermaLink='false']">
<xsl:text>#</xsl:text>
</xsl:if>
<xsl:value-of select="guid" />
</xsl:attribute>
<xsl:text>#</xsl:text>
</a>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="pubDate">
<span class="timestamp"><xsl:value-of select="pubDate" /></span>
</xsl:if>
<xsl:if test="pubDate and (category or link)">
<xsl:text> &#8212; </xsl:text>
</xsl:if>
<xsl:for-each select="category">
<span class="category"><xsl:value-of select="." /></span>
<xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if>
</xsl:for-each>
<xsl:if test="category and link">
<xsl:text> &#8212; </xsl:text>
<xsl:if test="title or link or category or pubDate or guid">
<header>
<xsl:if test="title">
<h2><xsl:value-of select="title" /></h2>
</xsl:if>
<xsl:if test="link">
<a href="{link}" target="_blank"><xsl:value-of select="link" /></a>
<p>
<a href="{link}" target="_blank">
<xsl:value-of select="link" />
</a>
</p>
</xsl:if>
</p>
<xsl:if test="pubDate">
<p>
<time><xsl:value-of select="pubDate" /></time>
</p>
</xsl:if>
</header>
</xsl:if>
<xsl:if test="description">
<div class="unescape">
<xsl:value-of select="description" disable-output-escaping="yes" />
</div>
<xsl:if test="category or guid or source or author">
<!-- TODO: Support comments and slashdot comments count -->
<footer>
<p>
<xsl:if test="category">
<span>
<xsl:text>Categories: </xsl:text>
<xsl:for-each select="category">
<xsl:value-of select="." />
<xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if>
</xsl:for-each>
</span>
</xsl:if>
<xsl:if test="category and (source or author)">
<xsl:text> &#8212; </xsl:text>
</xsl:if>
<xsl:if test="author">
<xsl:text>Written by </xsl:text>
<xsl:value-of select="author" />
</xsl:if>
<xsl:if test="author and source">
<xsl:text> &#8212; </xsl:text>
</xsl:if>
<xsl:if test="source">
<a href="{source}" target="_blank">Source</a>
</xsl:if>
<xsl:if test="guid">
<a class="permalink">
<xsl:attribute name="href">
<xsl:if test="guid[@isPermaLink='false']">
<xsl:text>#</xsl:text>
</xsl:if>
<xsl:value-of select="guid" />
</xsl:attribute>
<xsl:text>(permalink)</xsl:text>
</a>
</xsl:if>
</p>
</footer>
</xsl:if>
</article>
</xsl:template>
</xsl:stylesheet>
</xsl:stylesheet>