Copy the tweet in TweetDeck.
// ==UserScript==
// @name TweetDeck-PakuTwi
// @namespace tadamonohoshi
// @description Copy the tweet in TweetDeck.
// @version 0.2
// @grant none
// @include https://tweetdeck.twitter.com/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js
// ==/UserScript==
(function() {
// 設定
var DEBUG_MODE = false; // デバッグモード
var PAKU_WITH_FAV = true; // ふぁぼってパクる
var FLG = true; // 初期化用フラグ
function pakuTwi(e) {
var parent; // ツイート本体
var replyElem; // リプライ判定用要素
var text; // ツイート文字列
var evt; // イベントオブジェクト
// Ctrl・Shiftキー判定
if (e.ctrlKey) {
debug('Ctrl Mode On');
}
if (e.shiftKey) {
debug('Shift Mode On');
}
// ツイート本体を取得
parent = $(e.target).parents('.js-tweet');
// ツイートの文字列を取得
text = $(parent).find('.tweet-text').html();
// 絵文字、URLを変換後、HTMLタグを除去
text = text.replace(/<img class="emoji" draggable="false" alt="([^"]*)" src="([^"]*)">/g, '$1')
.replace(/<a href="([^"]*)" target="_blank" class="url-ext"[^>]*>[^<]*<\/a>/g, '$1')
.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, '');
// "&"・"<"・ ">"の置換
text = text.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
// Shiftキー押しながらで本文中の@username書き換え (試験的)
if (e.shiftKey) {
// 元ツイート主の@usernameを取得
var tweetBy = $(parent).find('.username').html().match(/@[a-zA-Z0-9_]{1,15}/g);
if (tweetBy) {
// うまく取得できたら本文中の@usernameを元ツイート主のもので書き換え
text = text.replace(/@[a-zA-Z0-9_]{1,15}/g, tweetBy);
}
}
// リプライ処理
replyElem = $(parent).find('.other-replies');
if (!e.shiftKey && replyElem.length > 0) {
var replyTo = replyElem.html().match(/@[a-zA-Z0-9_]{1,15}/g);
var unInText = text.match(/@[a-zA-Z0-9_]{1,15}/g);
debug('Reply To: ' + replyTo.join(' '));
if (!unInText) {
// 本文中に@usernameを含まない場合: @usernameを先頭に付加
text = replyTo.join(' ') + ' ' + text;
} else {
// 本文中に@usernameを含む場合: リプライ相手の@usernameが本文中になければリストに追加
var unList = [];
replyTo.forEach(function(un) {
var idx = unInText.indexOf(un);
if (idx < 0) {
unList.push(un);
}
});
// リストが空でなければリスト内の@usernameを先頭に付加
if (unList.length > 0) {
text = unList.join(' ') + ' ' + text;
}
}
}
// 入力エリアに文字列を挿入
debug(text);
$('textarea').val(text);
// 入力エリアのchangeイベントを強制発火 (文字数カウントさせる)
evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, false);
$('textarea').get(0).dispatchEvent(evt);
// ふぁぼる
if (e.ctrlKey && PAKU_WITH_FAV) {
$(parent).find('.js-icon-favorite').click();
}
// ツイートボタン押下
if (e.ctrlKey) {
$('.js-send-button').click();
}
}
function debug(s) {
if (DEBUG_MODE) {
console.log(s);
}
}
function appendButton(node) {
var target; // ボタン挿入先
var src; // ボタンHTMLソース
var item; // ボタン
// ボタン挿入先を取得
target = $(node).find('.js-tweet-actions .tweet-action-item:nth-child(3)');
// ボタンを定義
src = '<li class="tweet-action-item pull-left margin-r--13 margin-l--1"><a class="tweet-action position-rel" href="#">パクる</a></li>';
// ボタンを生成
item = $(src).insertAfter(target);
// ボタンにclickイベントのリスナーを設定
$(item).find('a').get(0).addEventListener('click', pakuTwi);
}
while (FLG) {
if ($('.application').length > 0) {
// applicationクラスのDOMが生成されたらDOMの監視を開始
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
// 追加されたDOMがjs-stream-itemクラスであればボタン追加処理を実行
if (node.nodeType == node.ELEMENT_NODE && node.classList.contains('js-stream-item')) {
appendButton(node);
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
FLG = false;
}
}
})();