Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save SergeAgeyev/d780cc50b3612f022a6b4a702e9643b2 to your computer and use it in GitHub Desktop.
Save SergeAgeyev/d780cc50b3612f022a6b4a702e9643b2 to your computer and use it in GitHub Desktop.
Show MDN browser release date on Browser compatibility list
// ==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