您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Shows full timestamps on Facebook posts
当前为
// ==UserScript== // @name FB: Full Timestamps 2019 // @match https://www.facebook.com/* // @match https://*.facebook.com/* // @match http://www.facebook.com/* // @match http://*.facebook.com/* // @run-at document-start // @grant GM_addStyle // @author wOxxOm & JZersche // @require http://greasyfork.icu/scripts/12228/code/setMutationHandler.js // @ require https://momentjs.com/downloads/moment.min.js // @ require https://momentjs.com/downloads/moment-with-locales.min.js // @version 3.06 // @namespace http://greasyfork.icu/users/95175 // @description Shows full timestamps on Facebook posts // ==/UserScript== var options = { weekday: 'long', year: 'numeric', month: 'numeric', day: '2-digit' }; GM_addStyle( '.full-timestamp { opacity: 0.95; color: #f00!important; }' + '.full-timestamp:hover { opacity: 1.0; }' + '.full-timestamp:before { content: ""; }' + '.full-timestamp:after { content: ""; }' + '.timestampContent {display: inline-block; }' + '.sponsored {color: #06b;}' ); // process the already loaded portion of the page if any expandDates(document.querySelectorAll('abbr[data-utime]')); RecentTimestamps(document.querySelectorAll('.q_1zif-zjsq')); RecentPostURLs(document.querySelectorAll('.q_1zif-zjsq, ._5r69, ._6ks')); ExternalURLs(document.querySelectorAll('._52c6')); expandPostIDs(document.querySelectorAll('._5pcq')); // process the stuff added from now on setMutationHandler(document, 'abbr[data-utime]', expandDates); setMutationHandler(document, '.q_1zif-zjsq', RecentTimestamps); setMutationHandler(document, '.q_1zif-zjsq, ._5r69, ._6ks', RecentPostURLs); setMutationHandler(document, '._52c6', ExternalURLs); setMutationHandler(document, '._5pcq', expandPostIDs); function pad(n, width, z) { z = z || '0'; n = n + ''; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; } function expandDates(nodes) { for (var i = 0, abbr; (abbr = nodes[i++]);) { if (abbr.querySelector('.full-timestamp')) { // already processed continue; } abbr.insertAdjacentHTML( 'beforeend', '<span class="full-timestamp">' + ' on ' + moment(new Date(abbr.dataset.utime * 1000)).format('l \\at LTS') ); } } function RecentTimestamps(nodes) { for (var i = 0, abbr; (abbr = nodes[i++]);) { if (abbr.querySelector('.full-timestamp')) { // already processed continue; } if (abbr.innerText.includes('min') == true) { var minAdjust = abbr.innerText.match(/[0-9]{1,2}/); var minAdjustI = parseInt(minAdjust, 10); abbr.insertAdjacentHTML( 'beforeend', '<span class="full-timestamp">' + ' <span style="color:#365899">(' + moment(new Date()) .subtract(minAdjustI, 'minutes').format('h:mm:ss A') + ' ≃ <span style="color:#365899">ᴀᴘᴘʀᴏxɪᴍᴀᴛᴇ)</span><br>' ); } if (abbr.innerText.includes('hr') == true) { // If innerText includes 'hr' in it (x hrs ago) var hrAdjust = abbr.innerText.match(/[0-9]{1,2}/); // Restrict the innerText to show only 1 or 2 numbers. |xx| var hrAdjustI = parseInt(hrAdjust, 10); // Convert |xx| to Integer from original String Format. var minRoundedDown = parseInt(moment(new Date()).format('mm') / 10, 10) * 10; // Return the current minute of the time, and round it down to the nearest 10. var secRoundedDown = parseInt(moment(new Date()).format('ss') / 10, 10) * 10; // Return the current minute of the time, and round it down to the nearest 10. abbr.insertAdjacentHTML( 'beforeend', '<span class="full-timestamp">' + ' <span style="color:#365899">on ' + moment(new Date()) .subtract(hrAdjustI, 'hours').format('l \\at h:') + pad(minRoundedDown, 2) + ':' + pad(secRoundedDown, 2) + '<span style="color:#365899"> ≃ (ᴀᴘᴘʀᴏxɪᴍᴀᴛᴇ)</span><br>' ); } } } function RecentPostURLs(nodes) { for (var i = 0; i < nodes.length; i++) { var element = nodes[i]; if (element.innerHTML.includes('<br>') === false && element.className != '_5r69') { element.getElement element.insertAdjacentHTML( 'afterend', '<br><span style="color:#9c9dc3">' + element.parentNode.parentNode.parentNode.parentNode.parentNode .parentNode.parentNode.parentNode.parentNode.previousSibling.href .replace(/\?fref=nf/, '').replace('&__tn__=', '').replace('&__tn__=m-R','').replace('7%2Cdm-R-R', '').replace('%2Cdm-R-R', '').replace(/&eid=.+/,'') .match(/facebook.com\/[a-z|A-Z|[0-9|\-|_|.]+.[a-zA-Z|[0-9|\-|_|.|]+[a-zA-Z|[0-9|\-|_|.|?=]+/) + '</span>' ); } } } function ExternalURLs(nodes) { for (var i = 0; i < nodes.length; i++) { var element = nodes[i]; var urlString = element.href.replace(/https:\/\/l\.facebook.com\/l.php\?u=/,''); if (element.innerHTML.includes('<br>') === false && element.className != '_5r69') { element.insertAdjacentHTML( 'afterend', '<span style="color:#2233ff">' + decodeURIComponent(urlString.replace(/\+/g, ' ')).replace(/.fbclid=[\D}\d]+/,'') + '</span>' ); } } } function expandPostIDs(e) { for (var r = 0; r < e.length; r++) { var p = e[r]; !1 === p.innerHTML.includes("<br>") && "_5pcq" === p.className && p.insertAdjacentHTML("beforeend", "<br>" + p.href.replace(/(\?__xts__%.+|\/\?type=\d&__xts__%.+)/gm, "").replace("permalink.php?", " permalink.php?").replace("/groups/", "Group: ").replace("/permalink/", "<br>Post ID: ").slice(24, 100).replace("/", "")); } }