Check for and fix problems in news articles

- Add missing target="_blank" attributes so links open externally
- Fix date format consistency
- Automate checking for issues
main
Isaiah Odhner 2022-08-01 15:36:05 -04:00
parent ecc19554c9
commit ccafef3445
2 changed files with 98 additions and 6 deletions

View File

@ -119,6 +119,18 @@
<p>Support the project at <a href="https://www.paypal.me/IsaiahOdhner"
target="_blank">paypal.me/IsaiahOdhner</a>.</p>
</div>
<script defer src="src/test-news.js"></script>
<!--
Before publishing a news update, make sure:
- The <time> element matches the date of the update.
- The id of the <article> will never need to be changed.
I'm using the format "news-YYYY-very-brief-description".
Avoiding putting the date in the id, in case I push the update later.
The id is used to check for updates, and is stored in localStorage.
- The console shows no errors.
test-news.js checks for some problems.
- HTML is valid.
-->
<div id="news" hidden>
<!-- <article class="news-entry" id="news-2021-saving">
<h1>The Savior Update</h1>
@ -168,15 +180,15 @@
</article> -->
<article class="news-entry" id="news-2022-open-source">
<h1>Open Source</h1>
<time datetime="2022-07-28">July 28, 2022</time>
<time datetime="2022-07-28">2022-07-28</time>
<!-- <img width="" height="" style="max-width: 100%; height: auto; image-rendering: auto;" alt="" src="" /> -->
<p>
JS Paint is now finally open source, licensed under the
<a href="https://github.com/1j01/jspaint/blob/master/LICENSE.txt">MIT License</a>.
<a href="https://github.com/1j01/jspaint/blob/master/LICENSE.txt" target="_blank">MIT License</a>.
</p>
<p>
The project has been <a
href="https://en.wikipedia.org/wiki/Source-available_software">source-available</a>
The project has been
<a href="https://en.wikipedia.org/wiki/Source-available_software" target="_blank">source-available</a>
from the beginning, since I never felt the need to obfuscate or hide the code,
but it is now legally open source.
</p>
@ -186,7 +198,7 @@
<p>
There is not yet a formal API for JS Paint,
but if you want to get in on the cutting edge,
you can take a look at how <a href="https://98.js.org">98.js.org</a>
you can take a look at how <a href="https://98.js.org" target="_blank">98.js.org</a>
embeds JS Paint.
Expect the API to change significantly in the future.
</p>
@ -271,7 +283,7 @@
It also includes projects from other people, other recreations of old programs,
like <a target="_blank" href="https://webamp.org/">Webamp</a>,
a meticulous recreation of Winamp,
and <a href="https://github.com/rjanjic/js-solitaire">JS Solitaire</a>,
and <a target="_blank" href="https://github.com/rjanjic/js-solitaire">JS Solitaire</a>,
a Solitaire clone (I tweaked it for accuracy, adding the card back images, etc.)
</p>
<h2>Pixel Perfect</h2>

80
src/test-news.js Normal file
View File

@ -0,0 +1,80 @@
/*
Automated checks to catch errors before publishing a news update:
- The <time> element's datetime attribute is set to the date of the update.
- The <time> element's text content is set to the date of the update.
- The id of the <article> is unique and follows the format 'news-YYYY-some-topic'.
- All <a> elements have a target="_blank" attribute.
- All <a> elements have an href attribute.
HTML validity checking is not performed.
*/
const newsEl = document.querySelector('#news');
const articles = newsEl.querySelectorAll('article');
const articleIDs = [];
for (const article of articles) {
// Check id
if (articleIDs.includes(article.id)) {
console.error(`Duplicate article id: #${article.id}`, article);
}
articleIDs.push(article.id);
if (!article.id.startsWith('news-')) {
console.error(`Article id does not start with 'news-': #${article.id}`, article);
}
// Check date
const time = article.querySelector('time');
if (!time) {
console.error(`Missing <time> element in article #${article.id}`, article);
} else {
const datetime = time.getAttribute('datetime');
const dateText = time.textContent;
if (!datetime) {
console.error(`Missing datetime attribute in <time> element in article #${article.id}`, time);
}
if (!dateText) {
console.error(`Missing text content in <time> element in article #${article.id}`, time);
}
// This doesn't handle time zones:
// if (new Date(datetime).toUTCString() !== new Date(dateText).toUTCString()) {
// console.error(
// `Mismatch between datetime attribute and text content in <time> element in article #${article.id}`,
// time,
// `\ndatetime: ${datetime}`,
// `\ntext: ${dateText}`,
// `\n${new Date(datetime).toUTCString()} !== ${new Date(dateText).toUTCString()}`
// );
// }
// I'm just using ISO 8601 date format for now.
if (datetime && dateText && datetime !== dateText) {
console.error(
`Mismatch between datetime attribute and text content in <time> element in article #${article.id}`,
time,
`\n${JSON.stringify(datetime)} !== ${JSON.stringify(dateText)}`
);
}
if (datetime) {
// Check id matches date
const expectedYYYY = new Date(datetime).getFullYear().toString();
if (!article.id.includes(`-${expectedYYYY}-`)) {
console.error(`Article id does not contain expected year: #${article.id}`,
`\nexpected: "-${expectedYYYY}-"`,
`\nactual: ${JSON.stringify(article.id.substring(4, 10))}`
);
}
}
}
// Check links
const links = article.querySelectorAll('a');
for (const link of links) {
const target = link.getAttribute('target');
const href = link.getAttribute('href');
if (target !== '_blank') {
console.error(`target is not "_blank"`, link);
}
if (!href) {
console.error(`href is not set`, link);
}
}
}