您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add "Retweet with comments" link to tweets
- // ==UserScript==
- // @name Twitter Non-native Retweet MOD
- // @version 1.0.140930
- // @namespace @sapikachu
- // @description Add "Retweet with comments" link to tweets
- // @include http://twitter.com/*
- // @include https://twitter.com/*
- // @grant none
- // ==/UserScript==
- (function() {
- // http://wiki.greasespot.net/Content_Script_Injection
- function contentEval(source) {
- // Check for function input.
- if ('function' == typeof source) {
- // Execute this function with no arguments, by adding parentheses.
- // One set around the function, required for valid syntax, and a
- // second empty set calls the surrounded function.
- source = '(' + source + ')();'
- }
- // Create a script node holding this source code.
- var script = document.createElement('script');
- script.setAttribute("type", "application/javascript");
- script.textContent = source;
- // Insert the script node into the page, so it will run, and immediately
- // remove it to clean up.
- document.body.appendChild(script);
- document.body.removeChild(script);
- }
- function register() {
- // originally by @jamespgilbert (http://userscripts.org/scripts/show/70467), modified by @SAPikachu
- var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
- // Save or make a fake console object for debugging
- var console = {};
- for (var i = 0; i < names.length; i++) {
- if (window["console"]) {
- console[names[i]] = window.console[names[i]];
- } else {
- console[names[i]] = function() {};
- }
- }
- // Twitter disables console object after loading, we make it available again for using in firebug
- window._console = console;
- window.showRetweetBox = function (link) {
- setTimeout(function() {
- var impl = function($) {
- try
- {
- var tweetElem = $(link).parents().filter(".js-actionable-tweet").eq(0);
- if (tweetElem.size() == 0) {
- alert("Can't locate tweet element.");
- return;
- };
- var userElem = tweetElem.find(".account-group .username b").eq(0);
- var userName = $.trim(userElem.html());
- if (!userElem.length) {
- userElem = tweetElem.find(".ProfileTweet-originalAuthor .ProfileTweet-screenname");
- userName = $.trim(userElem.text()).substr(1);
- }
- var contentElem = $(".js-tweet-text", tweetElem).eq(0).clone();
- $("a", contentElem).each(function() {
- var o = $(this);
- var expanded = o.data("ultimate-url") || o.data("expanded-url");
- if (expanded) {
- o.text(expanded);
- };
- });
- var content = " RT @" + userName + " " + $.trim(contentElem.text());
- $("#global-new-tweet-button").trigger(
- "uiOpenTweetDialog",
- {
- defaultText: content,
- canTweetDefaultText: !0,
- cursorPosition: 0
- }
- );
- // Dirty hack to preserve conversation stream
- // Seems tweetElem.data("tweet-id") will parse the
- // id as float and give us wrong result
- $(document).trigger(
- "uiOverrideTweetBoxOptions",
- { id: tweetElem.attr("data-tweet-id") }
- );
- } catch (e) {
- console.error(e);
- }
- };
- if (window["jQuery"]) {
- impl(window["jQuery"]);
- } else {
- // Use loadrunner from the page
- using("core/jquery", impl);
- }
- }, 0);
- };
- function insertRetweetLink(parent, text) {
- if (parent.getElementsByClassName("action-rtwc-container").length > 0) {
- return;
- }
- var ref = parent.getElementsByClassName("action-fav-container")[0];
- var realrt = document.createElement("li");
- realrt.className = "action-rtwc-container";
- realrt.innerHTML = '<a href="#" onclick="showRetweetBox(this); return false;" class="with-icn"><span class="Icon Icon--retweet" style="color: inherit"></span> <b>' + text + '</b></a>';
- parent.insertBefore(realrt, ref);
- }
- function insertRetweetLink2(parent, text) {
- if (parent.getElementsByClassName("ProfileTweet-action--rtwc").length > 0) {
- return;
- }
- var ref = parent.getElementsByClassName("ProfileTweet-action--favorite")[0];
- var realrt = document.createElement("div");
- realrt.className = "ProfileTweet-action ProfileTweet-action--retweet ProfileTweet-action--rtwc js-toggle-state js-toggle-rt";
- realrt.innerHTML = '<button title="Retweet with comment" href="#" onclick="showRetweetBox(this); return false;" class="ProfileTweet-actionButton js-tooltip js-actionButton"><span class="Icon Icon--retweet" style="color: inherit"></span> <span class="u-isHiddenVisually">' + text + '</span></button>';
- parent.insertBefore(realrt, ref);
- }
- function addRetweetLink(item) {
- var actionsArray;
- try {
- actionsArray = item.getElementsByClassName("tweet-actions") || [];
- } catch (e) {
- return;
- }
- for (var i = 0; i < actionsArray.length; i++) {
- insertRetweetLink(actionsArray[i], "RT w/ C");
- }
- try {
- actionsArray = item.getElementsByClassName("ProfileTweet-actionList") || [];
- } catch (e) {
- return;
- }
- for (var i = 0; i < actionsArray.length; i++) {
- insertRetweetLink2(actionsArray[i], "w/ C");
- }
- }
- function addMultipleRetweetLinks(elements) {
- if (elements.length > 0) {
- for (var i = 0; i < elements.length; i++) {
- // due to some unknown reason, we need to create a scope and capture the node object, otherwise something strange will happen (elements will be cleared etc.)
- (function() {
- var node = elements[i];
- setTimeout(function() {
- addRetweetLink(node);
- }, 0);
- })();
- }
- }
- }
- function addMultipleRetweetLinksForContainer(klass) {
- var container = document.getElementsByClassName(klass);
- if (container.length) {
- tweets = container[0].getElementsByClassName("js-stream-tweet");
- addMultipleRetweetLinks(tweets);
- }
- }
- function addLinksToTimeline() {
- var timeline = document.getElementById("timeline") || document.getElementById("discover_items");
- var tweets;
- if (timeline) {
- tweets = timeline.getElementsByClassName("js-stream-item");
- addMultipleRetweetLinks(tweets);
- }
- tweets = document.getElementsByClassName("permalink-tweet");
- if (tweets.length) {
- addMultipleRetweetLinks(tweets);
- addMultipleRetweetLinksForContainer("permalink-in-reply-tos");
- addMultipleRetweetLinksForContainer("permalink-replies");
- }
- addMultipleRetweetLinksForContainer("GridTimeline");
- }
- function setupTimeline() {
- addLinksToTimeline();
- var timeline = document.getElementById("timeline");
- var observer = new MutationObserver(function(mutations) {
- mutations.forEach(function(mutation) {
- if (mutation.addedNodes) {
- for (var i = 0; i < mutation.addedNodes.length; i++) {
- var target = mutation.addedNodes[i];
- if (!target.getElementsByClassName) {
- continue;
- }
- var cl = target.className || "";
- if (cl.indexOf("js-stream-tweet") >= 0 || cl.indexOf("stream-item") >= 0) {
- addRetweetLink(target);
- } else if (cl.indexOf("js-conversation-replies")) {
- replies = target.getElementsByClassName("js-actionable-tweet");
- addMultipleRetweetLinks(replies);
- } else if (target.id === "timeline") {
- addLinksToTimeline();
- }
- }
- }
- });
- });
- observer.observe(document.body, { subtree: true, childList: true });
- }
- if (document.readyState == "complete" || document.readySate == "loaded" || document.readyState == "interactive") {
- setupTimeline();
- } else {
- document.addEventListener(
- 'DOMContentLoaded', setupTimeline, false
- );
- }
- }
- contentEval(register);
- })();