// ==UserScript==
// @name [Twitter]長いツイートをTLで展開
// @name:ja [Twitter]長いツイートをTLで展開
// @name:en [Twitter]Note_Tweet expander
// @version 1145141919810.0.3
// @description 長いツイートを「更に表示」を押さなくてもTLで展開します。
// @description:ja 長いツイートを「更に表示」を押さなくてもTLで展開します。
// @description:en Long tweets will expand in the TimeLine without having to press "Show More".
// @author ゆにてぃー
// @match https://twitter.com/*
// @match https://mobile.twitter.com/*
// @connect api.twitter.com
// @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant GM_xmlhttpRequest
// @license MIT
// @namespace https://greasyfork.org/ja/users/1023652
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
const cookies = getCookieArray();
let updating = false;
window.addEventListener("scroll", update);
init();
async function main(){
const link_class = "r-18u37iz css-4rbku5 css-18t94o4 css-901oao css-16my406 r-1cvl2hr r-1loqt21 r-poiln3 r-bcqeeo r-qvutc0";
document.querySelectorAll('span[data-testid="tweet-text-show-more-link"]').forEach(async function(element){
const tweet_id = Array.from(element.parentNode.parentNode.parentNode.parentNode.querySelectorAll("a[aria-label]")).filter(function(tmp){return tmp.href.match(/\/status\/[0-9]*(\/analytics)?$/)})[0].href.match(/status\/(\d+)/)[1];
const response_data = await request(new requestObject_twitter(tweet_id,cookies));
const twitter_qraphql_json = response_data.data.threaded_conversation_with_injections.instructions[0];
const tweet_data = twitter_qraphql_json.entries[twitter_qraphql_json.entries.findIndex((tmp) => tmp.entryId == `tweet-${tweet_id}`)].content.itemContent.tweet_results;
const note_tweet = tweet_data.result.note_tweet.note_tweet_results.result;
const hashtags = get_only_particular_key_value(note_tweet.entity_set.hashtags,"text");
const user_mentions = get_only_particular_key_value(note_tweet.entity_set.user_mentions,"screen_name");
const urls = note_tweet.entity_set.urls;
const tweet_node = element.parentNode.parentNode.querySelector('[data-testid="tweetText"]');
var new_tweet_text = note_tweet.text;
hashtags.forEach(target =>{
new_tweet_text = new_tweet_text.replace(`#${target}`,`#${target}`)
});
user_mentions.forEach(target =>{
new_tweet_text = new_tweet_text.replace(`@${target}`,`@${target}`)
});
urls.forEach(target =>{
new_tweet_text = new_tweet_text.replace(`${target.url}`,`${target.display_url}`)
});
var new_tweet_node = document.createElement("span");
new_tweet_node.className = 'css-901oao css-16my406 r-1tl8opc r-bcqeeo r-qvutc0';
new_tweet_node.innerHTML = new_tweet_text;
while (tweet_node.firstChild) {
tweet_node.removeChild(tweet_node.firstChild);
}
tweet_node.appendChild(new_tweet_node);
element.remove();
})
}
function init() {
main();
}
function update() {
if(updating) return;
updating = true;
init();
setTimeout(() => {updating = false;}, 1500);
}
function get_only_particular_key_value(object, path, defaultValue = undefined){
var isArray = Array.isArray;
if(object == null || typeof object != 'object') return defaultValue;
return (isArray(object)) ? object.map(createProcessFunction(path)) : createProcessFunction(path)(object);
function createProcessFunction(path){
if(typeof path == 'string') path = path.split('.');
if(!isArray(path)) path = [path];
return function(object){
var index = 0,
length = path.length;
while(index < length){
const key = toString_(path[index++]);
if(object === undefined){
return defaultValue;
}
if(isArray(object)){
object = object.map(item => item[key]);
}else{
object = object[key];
}
}
return (index && index == length) ? object : void 0;
};
}
function toString_(value){
if(value == null) return '';
if(typeof value == 'string') return value;
if(isArray(value)) return value.map(toString) + '';
var result = value + '';
return '0' == result && 1 / value == -(1 / 0) ? '-0' : result;
}
}
function getCookieArray() {
var arr = [];
if(document.cookie != '') {
var tmp = document.cookie.split('; ');
for(var i = 0; i < tmp.length; i++) {
var data = tmp[i].split('=');
arr[data[0]] = decodeURIComponent(data[1]);
}
}
return arr;
}
async function request(object, timeout = 60000) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: object.method,
url: object.url,
headers: object.headers,
responseType: object.respType,
data: object.body,
anonymous: object.anonymous,
timeout: timeout,
onload: function(responseDetails) {
return resolve(responseDetails.response);
},
ontimeout: function(responseDetails) {
reject(`[request]time out:\nresponse ${responseDetails}`)
},
onerror: function(responseDetails) {
reject(`[request]error:\nresponse ${responseDetails}`)
}
});
});
}
class requestObject_twitter {
constructor(ID, cookies) {
this.method = 'GET';
this.respType = 'json';
this.url = `https://api.twitter.com/graphql/NNiD2K-nEYUfXlMwGCocMQ/TweetDetail?variables=%7B%22focalTweetId%22%3A%22${ID}%22%2C%22with_rux_injections%22%3Afalse%2C%22includePromotedContent%22%3Atrue%2C%22withCommunity%22%3Afalse%2C%22withQuickPromoteEligibilityTweetFields%22%3Atrue%2C%22withBirdwatchNotes%22%3Afalse%2C%22withSuperFollowsUserFields%22%3Atrue%2C%22withDownvotePerspective%22%3Afalse%2C%22withReactionsMetadata%22%3Afalse%2C%22withReactionsPerspective%22%3Afalse%2C%22withSuperFollowsTweetFields%22%3Atrue%2C%22withVoice%22%3Atrue%2C%22withV2Timeline%22%3Afalse%7D&features=%7B%22responsive_web_twitter_blue_verified_badge_is_enabled%22%3Atrue%2C%22responsive_web_graphql_exclude_directive_enabled%22%3Afalse%2C%22verified_phone_label_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Afalse%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22tweetypie_unmention_optimization_enabled%22%3Atrue%2C%22vibe_api_enabled%22%3Afalse%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Afalse%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Afalse%2C%22interactive_text_enabled%22%3Atrue%2C%22responsive_web_text_conversations_enabled%22%3Afalse%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D`;
this.body = null;
this.headers = {
"Content-Type": "application/json",
'User-agent': navigator.userAgent || navigator.vendor || window.opera,
'accept': '*/*',
'Referer': "https://twitter.com/",
'Host': 'api.twitter.com',
'authorization': `Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA`,
'x-csrf-token': cookies.ct0
};
this.package = null;
this.anonymous = false;
}
}
})();