您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A user script to show feed favicons in Feedly Title-Only View.
- // ==UserScript==
- // @name Feedly Faviconize List
- // @namespace jmln.tw
- // @version 0.2.7
- // @description A user script to show feed favicons in Feedly Title-Only View.
- // @author Jimmy Lin
- // @license MIT
- // @homepage https://github.com/jmlntw/feedly-faviconize-list
- // @supportURL https://github.com/jmlntw/feedly-faviconize-list/issues
- // @match https://*.feedly.com/*
- // @compatible firefox
- // @compatible chrome
- // @compatible opera
- // @run-at document-end
- // @grant none
- // ==/UserScript==
- function addStyle (css) {
- const style = document.createElement('style')
- style.textContent = css
- document.head.appendChild(style)
- return style
- }
- addStyle(`
- .gm-favicon {
- width: 16px;
- height: 16px;
- margin: 0 6px 0 0;
- padding: 0;
- border-radius: 3px;
- vertical-align: top;
- }
- `)
- function awaitSelector (selector, root) {
- return new Promise((resolve, reject) => {
- try {
- const rootElement = root ?
- typeof root === 'string' ? document.querySelector(root) : root :
- document
- const findAndResolveElements = () => {
- const allElements = document.querySelectorAll(selector)
- const newElements = []
- const resolvedAttr = 'data-awaitselector-resolved'
- if (allElements.length > 0) {
- Array.prototype.slice.call(allElements)
- .filter(element => typeof element[resolvedAttr] === 'undefined')
- .forEach(element => {
- element[resolvedAttr] = true
- newElements.push(element)
- })
- if (newElements.length > 0) {
- observer.disconnect()
- resolve(newElements)
- }
- }
- }
- const observer = new MutationObserver(mutations => {
- const addedNodes = mutations.reduce((found, mutation) => {
- return found || mutation.addedNodes && mutation.addedNodes.length > 0
- })
- if (addedNodes) {
- findAndResolveElements()
- }
- })
- observer.observe(rootElement, {
- childList: true,
- subtree: true
- })
- findAndResolveElements()
- } catch (exception) {
- reject(exception)
- }
- })
- }
- function waitAwaitSelector (selector, root, callback) {
- (function awaiter () {
- const continueWatching = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true
- if (continueWatching) {
- awaitSelector(selector, root).then(callback).then(awaiter)
- }
- }())
- }
- function createFavicon (url) {
- const domain = url.replace(/^https?:\/\/([^/:]+).*/i, '$1')
- const favicon = document.createElement('img')
- favicon.src = `https://www.google.com/s2/favicons?domain=${domain}&alt=feed`
- favicon.classList.add('gm-favicon')
- return favicon
- }
- awaitSelector('#feedlyPageFX', '#root').then(pages => {
- waitAwaitSelector('a.EntryMetadataSource[href]', pages[0], sources => {
- sources
- .filter(source => source.querySelector('.gm-favicon') === null)
- .forEach(source => {
- source.insertAdjacentElement('afterbegin', createFavicon(source.href))
- })
- })
- })