Last active
May 26, 2021 13:42
-
-
Save SergeAgeyev/d780cc50b3612f022a6b4a702e9643b2 to your computer and use it in GitHub Desktop.
Show MDN browser release date on Browser compatibility list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Show MDN browser release date on Browser compatibility list | |
// @namespace http://tampermonkey.net/ | |
// @version 0.3 | |
// @description Will show browser release date on Browser compatibility list as tooltip. On double click on table will add days ago on cells. (Code License: MIT License) | |
// @author Serge Ageyev @ openlab.vn.ua | |
// @match https://developer.mozilla.org/* | |
// ==/UserScript== | |
// Revision history: | |
// 0.1 : Initial implemenation | |
// 0.2 : Adapted to new layout of MDN | |
// 0.3 : Simplified to use MDN tooltip date as release date | |
(function() { | |
'use strict'; | |
function strTrim(s) { | |
return s.replace(/^[\n\r\s\uFEFF\xA0]+|[\n\r\s\uFEFF\xA0]+$/g, ''); | |
} | |
function getNodeOwnText(node) { | |
var result = ''; | |
var childNode; | |
for(var i = 0; i < node.childNodes.length; i++) { | |
childNode = node.childNodes[i]; | |
if (childNode.nodeType == 3) { | |
result += childNode.nodeValue; | |
} | |
} | |
return result; | |
} | |
function findBrowserId(cell) { | |
var PFX = 'bc-browser-'; | |
var cname; | |
for (var i = 0; i < cell.classList.length; i++) { | |
cname = cell.classList[i]; | |
if (cname.substring(0, PFX.length) == PFX) { | |
return cname.substring(PFX.length); | |
} | |
} | |
return null; | |
} | |
function findBrowserName(cell) { | |
var nameNodes = cell.querySelectorAll('.bc-browser-name'); | |
if (nameNodes.length > 0) { | |
return strTrim(nameNodes[0].innerText); | |
} | |
return null; | |
} | |
function findBrowserReleaseDateTextByCellTooltip(cell) { | |
try { | |
var str = cell.title; | |
if (str == null) { return null; } | |
const regex = /(\d{4})-(\d{2})-(\d{2})/; | |
var m; | |
if ((m = regex.exec(str)) !== null) { return m[0]; } | |
return null; | |
} catch(e) { | |
return null; | |
} | |
} | |
function createReleaseData(cell) { | |
var id = findBrowserId(cell); | |
if (id == null) { return null; } // give up | |
var name = findBrowserName(cell); | |
if (name == null) { return null; } // give up | |
var ver = strTrim(getNodeOwnText(cell)); | |
if (ver == null) { return null; } // give up | |
var releaseDateText = findBrowserReleaseDateTextByCellTooltip(cell); | |
if (releaseDateText == null) { return null; } // give up | |
var release = { }; | |
release.release_date = releaseDateText; | |
var releaseDate = null; | |
try { | |
releaseDate = new Date(releaseDateText); | |
} catch(e) { | |
// ignore | |
} | |
var diffDays = null; | |
var diffMonths = null; | |
var diffYears = null; | |
if (releaseDate != null) { | |
var nowDate = new Date(); | |
var diffTime = Math.abs(nowDate - releaseDate); | |
diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); | |
if (diffDays < 0) { | |
diffDays = 0; // TZ issues | |
} | |
diffMonths = Math.floor(diffDays / 30); | |
diffYears = +(diffMonths / 12).toFixed(1); | |
} | |
var myProp = { release: release, releaseDate : releaseDate, diffDays : diffDays, diffMonths : diffMonths, diffYears : diffYears }; | |
return myProp; | |
} | |
var MY_PROPERTY_NAME = 'tm.browser.release'; | |
function attachCellTooltip(cell) { | |
var myProp = cell[MY_PROPERTY_NAME]; | |
if (myProp == null) { return; } // giveup | |
var releaseDateText = myProp.release.release_date; | |
var tooltip = cell.title || ''; | |
if (strTrim(tooltip) == '') { | |
tooltip = releaseDateText; | |
} | |
if ((myProp.diffDays != null) && (myProp.diffMonths != null) && (myProp.diffYears != null)) { | |
tooltip += '\n(' + myProp.diffDays + 'days/' + myProp.diffMonths + 'months/' + myProp.diffYears + 'years ago)'; | |
tooltip += '\n[dblclick to show/hide all]'; | |
} | |
cell.title = tooltip; | |
} | |
var HINT_TAG = 'div'; | |
var HINT_STYLE = 'font-size:50%;position:relative;top:-4px'; | |
var HINT_CLASS = 'tm-browser-release-hint'; | |
function attachCellHintElement(cell) { | |
var myProp = cell[MY_PROPERTY_NAME]; | |
if (myProp == null) { return; } // giveup | |
if (myProp.diffYears != null) { | |
var hint = document.createElement(HINT_TAG); | |
hint.style = HINT_STYLE; | |
hint.className = HINT_CLASS; | |
hint.innerText = myProp.diffYears+'yrs'; | |
cell.appendChild(hint); | |
} | |
} | |
function detachCellHintElement(cell) { | |
var hint = cell.querySelector(HINT_TAG+'.'+HINT_CLASS); | |
if (hint != null) { | |
hint.parentNode.removeChild(hint); | |
} | |
} | |
function getHostTable() { | |
return document.querySelector('table.bc-table'); | |
} | |
function getTargetCells() { | |
return document.querySelectorAll('table.bc-table td.bc-supports-yes'); | |
} | |
function attachData() { | |
var browserCells = getTargetCells(); | |
var cell, data; | |
for (var i = 0; i < browserCells.length; i++) { | |
cell = browserCells[i]; | |
data = createReleaseData(cell); | |
if (data != null) { | |
cell[MY_PROPERTY_NAME] = data; | |
} | |
} | |
} | |
function attachTooltips() { | |
var browserCells = getTargetCells(); | |
for (var i = 0; i < browserCells.length; i++) { | |
attachCellTooltip(browserCells[i]); | |
} | |
} | |
// Attach on double click handler | |
var isHintsShown = false; | |
function attachHints() { | |
var browserCells = getTargetCells(); | |
for (var i = 0; i < browserCells.length; i++) { | |
attachCellHintElement(browserCells[i]); | |
} | |
isHintsShown = true; | |
} | |
function detachHints() { | |
var browserCells = getTargetCells(); | |
for (var i = 0; i < browserCells.length; i++) { | |
detachCellHintElement(browserCells[i]); | |
} | |
isHintsShown = false; | |
} | |
function onDoubleClick(e) { | |
if (!isHintsShown) { | |
attachHints(); | |
} else { | |
detachHints(); | |
} | |
} | |
function attachDoubleClick() { | |
var theTable = getHostTable(); | |
if (theTable != null) { | |
theTable.addEventListener('dblclick', onDoubleClick); | |
} | |
} | |
var NAME = 'Show MDN browser release date'; | |
function checkAndAttach() { | |
if (getHostTable() != null) { | |
attachData(); | |
attachTooltips(); | |
attachDoubleClick(); | |
console.log('Plugin::'+NAME+'::attached to table'); | |
return; | |
} | |
setTimeout(checkAndAttach, 100); // retry | |
} | |
console.log('Plugin::'+NAME+'::loaded'); | |
checkAndAttach(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment