返回首頁 

Greasy Fork is available in English.

Twitter Lists Sidebar

Show your Twitter Lists in sidebar


安装此脚本?
// ==UserScript==// @name        Twitter Lists Sidebar// @description Show your Twitter Lists in sidebar// @version     0.3// @grant       GM.xmlHttpRequest// @include     https://twitter.com/*// @namespace https://greasyfork.org/users/173161// ==/UserScript==// Note: Avoid using jQuery as it may not be avialble on page load yet(function(){// Cache data using localStorage or sessionStorage// class definion have to be placed before its usageclass Cache {constructor(){// Key name prefix. Avoid #####es with Twitter itselfthis.prefix = 'lists-sidebar:';// Use sessionStorage or localStoragethis.storage = window.sessionStorage;}get(name) {return this.storage.getItem(this.prefix + name);}set(name, value) {return this.storage.setItem(this.prefix + name, value);}clear() {for (let key in this.storage) {if (key.indexOf(this.prefix) === 0) {this.storage.removeItem(key);}}}}let usernameTag = document.querySelector('.DashUserDropdown-userInfo .username b');const username = usernameTag && usernameTag.innerText;// Not loginif (!username) {return;}const cache = new Cache();// Clear cache if user changedif (cache.get('username') && cache.get('username') !== username) {cache.clear();}let sidebar;// Execute once on page loadpageChanged();// Poll to detect page navigation.// Twitter.com is an SPA and thus document ready event is only fired once.// history.onpopstate event is not reliable as history.pushState does not trigger itlet currentPathname = location.pathname;setInterval(function(){if (location.pathname !== currentPathname) {currentPathname = location.pathname;pageChanged();}}, 300);function ajaxRequest(url, callback) {// "Referer" header is required for the request to succeed,// but native XMLHttpRequest does not alllow to set this header// https://wiki.greasespot.net/GM.xmlHttpRequestGM.xmlHttpRequest({method: 'GET',url: url,timeout: 3000,headers: {'Accept': 'application/json, text/javascript, */*; q=0.01','Referer': 'https://twitter.com/','X-Push-State-Request': 'true','X-Twitter-Active-User': 'yes','X-Requested-With': 'XMLHttpRequest',},onload: function(details) {callback(JSON.parse(details.responseText).page.replace(/\\n|\\/g, ''));},onerror: function() {callback(null);},ontimeout: function() {callback(null);}});}// Retrive lists by requesting lists page and parsing returned HTMLfunction retriveLists(username, callback) {const pattern = /<a class="ProfileListItem-name[^>]*href="([^"]+)">([^<]*)<\/a>/g;ajaxRequest('https://twitter.com/' + username + '/lists',function(html) {if (!html) {return;}let lists = [];let match = null;while (match = pattern.exec(html)) {lists.push({url: match[1],name: match[2],});}// Sort by namelists.sort(function(a, b){return a.name > b.name ? 1 : (a.name < b.name ? -1 : 0);});callback && callback(lists.length > 0 ? lists : null);});}function createSidebar(lists) {if (!lists || !lists.length) {return;}sidebar = document.createElement('sidebar');sidebar.id = 'lists-sidebar';// Reuse existing style for consistent color and backgroud-colorsidebar.className = 'DashboardProfileCard'let title = document.createElement('h3');title.innerHTML = 'Lists';sidebar.appendChild(title);let ul = document.createElement('ul');ul.id = 'sidebar-lists';sidebar.appendChild(ul);for (let i = 0; i < lists.length; i++) {let li = document.createElement('li');let a = document.createElement('a');a.className = 'js-nav u-textUserColor';a.href = lists[i].url;a.innerHTML = lists[i].name;li.appendChild(a);ul.appendChild(li);}document.body.appendChild(sidebar);addSidebarStyle();}function addSidebarStyle() {if (document.getElementById('lists-sidebar-style')) {return;}let style = document.createElement('style');style.id = 'lists-sidebar-style';style.innerHTML = `#lists-sidebar {position: fixed;left: 20px;top: 30%;padding: 1em 1.5em;line-height: 1.5;z-index: 1000000;}#lists-sidebar h3 {margin-bottom: 0.5em;text-align: center;}#lists-sidebar ul {margin: 0;padding: 0;list-style-type: disc;list-style-position: inside;}`;document.head.appendChild(style);}function updateSidebar() {// Cache only valid for 10 minuteslet lastUpdate = cache.get('lastUpdate');if (lastUpdate && new Date() - new Date(lastUpdate) > 600000) {cache.clear();removeSidebar();}// Already exists and do not need to updateif (sidebar) {return;}let lists = JSON.parse(cache.get('lists'));if (lists) {createSidebar(lists);} else {retriveLists(username, function(lists) {if (lists && lists.length > 0) {cache.set('lists', JSON.stringify(lists));cache.set('username', username);cache.set('lastUpdate', new Date().toString());createSidebar(lists);}});}}function removeSidebar() {if (sidebar) {sidebar.remove();sidebar = null;}}// Create or remove sidebar when page changed// Only show sidebar on homepage and lists related pagesfunction pageChanged() {if (location.pathname === '/' || /^\/[^/]+\/lists/.test(location.pathname)) {updateSidebar();} else {removeSidebar();}}}());