|
// ■ はてなブログの記事に更新日時表示&古い記事に警告を出す |
|
( async () => { |
|
'use strict'; |
|
|
|
const |
|
THRESHOLD_YEAR = 1, // THRESHOLD_YEAR 年以上前の記事に警告を出す |
|
|
|
get_path = ( url ) => new URL( url || location.href ).pathname; |
|
|
|
if ( document.querySelector( 'html' ).dataset.page != 'entry' ) return; |
|
|
|
let header_elem = document.querySelector( '#main-inner article.entry header.entry-header' ); |
|
|
|
if ( ! header_elem ) return; |
|
|
|
let time_info = ( () => { |
|
/* |
|
//let time_elem = document.querySelector( 'time[datetime][pubdate].updated' ); |
|
//if ( ! time_elem ) return null; |
|
//let date = new Date( time_elem.getAttribute( 'datetime' ) ); |
|
//return { |
|
// year : date.getFullYear(), |
|
// month : 1 + date.getMonth(), |
|
// day : date.getDate(), |
|
//}; |
|
*/ |
|
let time_elem = header_elem.querySelector( 'div.date a time[pubdate]' ); |
|
if ( ! time_elem ) return null; |
|
return { |
|
year : parseInt( time_elem.querySelector( '.date-year' ).textContent.trim(), 10 ), |
|
month : parseInt( time_elem.querySelector( '.date-month' ).textContent.trim(), 10 ), |
|
day : parseInt( time_elem.querySelector( '.date-day' ).textContent.trim(), 10 ), |
|
}; |
|
} )(); |
|
|
|
if ( ! time_info ) return; |
|
|
|
let sitemap_xml_url = new URL( '/sitemap_periodical.xml?year=' + time_info.year + '&month=' + time_info.month, location.href ).href, |
|
sitemap = await fetch( sitemap_xml_url ) |
|
.then( response => response.text() ) |
|
.then( ( xml_text ) => { |
|
return new DOMParser().parseFromString( xml_text, 'text/xml' ); |
|
} ) |
|
.catch( ( error ) => { |
|
console.error( 'fetch() or analyze error:', sitemap_xml_url, error ); |
|
} ); |
|
|
|
if ( ! sitemap ) return; |
|
|
|
let current_path = get_path(), |
|
matched_url_element = Array.from( sitemap.querySelectorAll( 'urlset > url' ) ) |
|
.filter( url_info => get_path( url_info.querySelector( 'loc' ).textContent ) == current_path )[ 0 ]; |
|
|
|
if ( ! matched_url_element ) return; |
|
|
|
let last_modified_string = matched_url_element.querySelector( 'lastmod' ).textContent, |
|
last_modified_date = new Date( last_modified_string ), |
|
last_modified_elem = document.createElement( 'time' ), |
|
threshold_date = ( threshold_date => threshold_date.setYear( threshold_date.getFullYear() - THRESHOLD_YEAR ) && threshold_date )( new Date () ); |
|
|
|
last_modified_elem.classList.add( 'last-modified' ); |
|
last_modified_elem.setAttribute( 'datetime', last_modified_date.toISOString() ); |
|
last_modified_elem.insertAdjacentHTML( 'beforeend', '最終更新日:' + last_modified_string.replace( /T.*$/, '' ) ); |
|
header_elem.querySelector( 'h1' ).after( last_modified_elem ); |
|
|
|
if ( threshold_date < last_modified_date ) return; |
|
|
|
let not_modified_years = Math.floor( ( Date.now() - last_modified_date.getTime() ) / Math.round( 365.2422 * 24 * 60 * 60 * 1000 ) ), |
|
warning_elem = document.createElement( 'div' ); |
|
|
|
warning_elem.classList.add( 'article-attention' ); |
|
warning_elem.insertAdjacentHTML( 'beforeend', 'この記事は ' + not_modified_years + ' 年以上更新されていません。<br />情報が古くなっているかもしれませんので、ご注意ください。' ); |
|
header_elem.after( warning_elem ); |
|
} )(); |
古い記事はこんな感じの警告が表示されます。