// ==UserScript==
// @name HomeTL/List/User/Searchページを自動更新する
// @namespace http://coltpythonkingcobra.g1.xrea.com/pseudoTweetdeck/
// @version 1.2.09301930
// @description TwitterWEBの各種ページの自動更新(停止可能)、タイトル文字列の置換と絶対時間表示などを行う
// @author
// @match https://twitter.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant none
// ==/UserScript==
//グローバル定義時用の汎用カウンタ
var gi_defIdx = 0;
/************************************************************
変更される事を考慮した各種const定義(var定義は変更しない事)
************************************************************/
//短周期タイマを一定時間後に停止する=1, 停止させず回ったままにする=0 (短周期タイマ切り替えボタンのクリックで変更可能)
const gi_defalutIdleShortTimer = 1;
var gi_idleShortTimer = gi_defalutIdleShortTimer;//※ここは変更しない
//相対時間を絶対時間表記にする=1, しない=0
const gi_replaceTimeStamp = 1;
//自動更新OFFモード スクロール位置やエディットのフォーカスによらず強制OFF=1, 従来の動作=0(自動更新ON/OFF切り替えボタンのクリックで変更可能)
const gi_defaultModeAutoOff = 0;
var gi_modeAutoOff = gi_defaultModeAutoOff;//※ここは変更しない
//Homeで上部の新着ツイートありの表示を勝手に押す=1, 押さない=0
const gi_autoClickNewTweet = 0;
//Homeで上部の新着ツイートありの表示を非表示にする=1, 非表示にしない=0(エディット表示切り替えボタンの右クリックで変更可能)
const gi_defaultHideNumberNewTweet = 0;
var gi_hideNumberNewTweet = gi_defaultHideNumberNewTweet;//※ここは変更しない
//設定更新時にポップアップメッセージを出しておく時間(秒) 出さない場合は0にする
const gi_displayPopupCloseTimeSec = 5;
//DOM更新の最終タイムスタンプを自動更新OFFでも表示する=1, 表示しない=0
const gi_enableTimeAutoOff = 1;
//既読ポイント用のチェックボックスを表示する=1, 表示しない=0
const gi_enableReadPointCheckBox = 1;
//同一のアーティクルをTLに複数表示しない(RTが並ばなくなる)表示しない=1, 表示する=0
const gi_notDispSameArticle = 1;
//Home上部のツイート欄を非表示にする=1, 表示したままにする=0 (エディット表示切り替えボタンクリックで変更可能)
const gi_defaultHideEditControl = 0;
var gi_hideEditControl = gi_defaultHideEditControl;//※ここは変更しない
//表示部+ボタンの不透明度(透明0.0〜1.0不透明 ※多分0.1刻みくらいでしか変化しない)
const gf_dispUnitOpacity = 1.0;
//表示部を左クリックで短周期タイマを再開させる=1, 再開させない=0
const gi_restartShortTimerL = 1;
//表示部を右クリックで短周期タイマを再開させる=1, 再開させない=0
const gi_restartShortTimerR = 0;
//表示部を左クリックした時に表示されている最新アーティクルを既読マークする=1, しない=0
const gi_defaultManualUpdateAutoCheckL = 1;
const gi_manualUpdateAutoCheckL = (gi_enableReadPointCheckBox) ? gi_defaultManualUpdateAutoCheckL : 0;//※ここは変更しない
//表示部を右クリックした時に表示されている最新アーティクルを既読マークする=1, しない=0
const gi_defaultManualUpdateAutoCheckR = 1;
const gi_manualUpdateAutoCheckR = (gi_enableReadPointCheckBox) ? gi_defaultManualUpdateAutoCheckR : 0;//※ここは変更しない
//表示部を左クリックで通知ページの新着表示を消去する=1, しない=0
const gi_clearNewNotificationL = 1;
//表示部を右クリックで通知ページの新着表示を消去する=1, しない=0
const gi_clearNewNotificationR = 1;
//表示部を左クリックで手動更新トリガをかける=1, トリガしない=0(但し、更新禁止間隔以内ではトリガしない)
const gi_manualUpdateTriggerL = 1;
//表示部を右クリックで手動更新トリガをかける=1, トリガしない=0(但し、更新禁止間隔以内ではトリガしない)
const gi_manualUpdateTriggerR = 1;
//表示部を左クリックで手動更新トリガをする時、自動更新が有効な状態(緑表示)では抑止する=1, 抑止しない=0
const gi_DefaultManualUpdateTriggerDisableGreenL = 1;
const gi_manualUpdateTriggerDisableGreenL = (gi_manualUpdateTriggerL) ? gi_DefaultManualUpdateTriggerDisableGreenL : 0;//※ここは変更しない
//表示部を右クリックで手動更新トリガをする時、自動更新が有効な状態(緑表示)では抑止する=1, 抑止しない=0
const gi_DefaultManualUpdateTriggerDisableGreenR = 0;
const gi_manualUpdateTriggerDisableGreenR = (gi_manualUpdateTriggerR) ? gi_DefaultManualUpdateTriggerDisableGreenR : 0;//※ここは変更しない
//表示部を左クリックで手動更新トリガをする時、自動更新が無効な状態(青表示)では抑止する=1, 抑止しない=0
const gi_DefaultManualUpdateTriggerDisableBlueL = 0;
const gi_manualUpdateTriggerDisableBlueL = (gi_manualUpdateTriggerL) ? gi_DefaultManualUpdateTriggerDisableBlueL : 0;//※ここは変更しない
//表示部を右クリックで手動更新トリガをする時、自動更新が無効な状態(青表示)では抑止する=1, 抑止しない=0
const gi_DefaultManualUpdateTriggerDisableBlueR = 1;
const gi_manualUpdateTriggerDisableBlueR = (gi_manualUpdateTriggerR) ? gi_DefaultManualUpdateTriggerDisableBlueR : 0;//※ここは変更しない
//更新トリガした直後の新着表示を自動的に押す=1, 押さない=0
const gi_manualUpdateTriggerNewTweet = 1;
//画像サムネイルを左クリックで別タブに画像表示する=1, しない=0
const gi_displayImageNewTab = 1;
//更新間隔定義(秒)=これを初期値として個別ページでインターバル変更ボタンをクリックすることで値の入力・保存が可能、最大3600だが強制再起動が先に掛かる可能性あり
const gi_updateIntervalMsHome = 30;
const gi_updateIntervalMsList = 300;
const gi_updateIntervalMsUser = 600;
const gi_updateIntervalMsNoti = 60;
const gi_updateIntervalMsSear = 180;
//更新間隔 [ unknown(未使用), Home, List, User、Notification(新着クリア), Search ]
const giA_defaultIntervalMs = [1000,
parseInt(gi_updateIntervalMsHome * 1000),
parseInt(gi_updateIntervalMsList * 1000),
parseInt(gi_updateIntervalMsUser * 1000),
parseInt(gi_updateIntervalMsNoti * 1000),
parseInt(gi_updateIntervalMsSear * 1000)]//※ここは変更しない
var giA_updateIntervalMs = giA_defaultIntervalMs;//※ここは変更しない
//短周期タイマを止めるまでの経過時間(ミリ秒)
const gi_shortTimerIdleMs = 10000;
//起動時待ち合わせ時間(ミリ秒)
const gi_initWaitMs = 10000;
//短周期タイマの間隔(ミリ秒)
const gi_shortIntervalMs = 250;
//スクロール位置が先頭に戻った後の短縮更新待ちあわせ時間(ミリ秒)
const gi_onTopWaitMs = 3000;
//強制リロード時の待ち合わせ時間(ミリ秒)
const gi_reloadWaitMs = 3000;
//強制リロード実施間隔初期値(秒)=これを初期値として個別ページでインターバル変更ボタンを右クリックすることで値の入力・保存が可能、最大7200だがTwitter独自の再起動が先に掛かる可能性あり
const gi_defaultReloadTimeoutSec = 3600;
var gi_reloadTimeoutSec = gi_defaultReloadTimeoutSec;//※ここは変更しない
//手動で更新をかけない経過時間(秒) ※自動更新インターバルの最小値としても使われる ※最後に更新をかけた時からこの設定時間以内は更新トリガ発行しない
const gi_defaultManualUpdateIntervalSec = 15;
var gi_manualUpdateIntervalSec = gi_defaultManualUpdateIntervalSec;//※ここは変更しない
//他のタブが強制リロードをしたら一定時間以内に強制リロードしない間隔時間(秒)
const gi_forceUpdateLockTimeSec = 120;
//マークする件数(最大100までにする事、ローカル保存データのキーを2桁[00〜99]にしているため)
const gi_readArticles = 8;
/***** ※色関係の定義を変えたらヘルプダイアログ中の説明文も変える *****/
const COLOR_GRAY = "rgba(255,255,255,0.3)";//初期色(非稼働)
const COLOR_BLACK = "rgba(0,0,0,1.0)";//完全非表示にする場合
const COLOR_WHITE = "rgba(255,255,255,1.0)";//モードの切り替えなどのメッセージ用
const COLOR_BORDER = "rgba(31,31,31,1.0)";//表示部枠の色
//情報表示部の色
const COLOR_UPDATE = "rgba(191,63,63,1.0)";//自動更新トリガ時の色
const COLOR_UPSOON = "rgba(191,191,63,1.0)";//自動更新トリガまで10秒以内の色
const COLOR_ACTIVE = "rgba(63,191,63,1.0)";//自動更新モード有効時の色
const COLOR_PAUSED = "rgba(63,63,191,1.0)";//自動更新の一時停止状態の色
const COLOR_HOLDTM = "rgba(63,191,191,1.0)";//手動更新抑止期間の色
const COLOR_RELOAD = "rgba(191,63,191,1.0)";//強制自動リロード10秒前の色
//インターバル設定ボタンの色
const COLOR_INT_DISABL = "rgba(127,127,127,0.5)";//初期値(非稼働)
const COLOR_INT_UPDATE = "rgba(191,63,63,1.0)";//自動更新トリガ時の色
const COLOR_INT_UPSOON = "rgba(191,191,63,1.0)";//自動更新トリガまで10秒以内の色
const COLOR_INT_ACTIVE = "rgba(63,191,63,1.0)";//自動更新モード有効時の色
const COLOR_INT_PAUSED = "rgba(63,63,191,1.0)";//自動更新の一時停止状態の色
const COLOR_INT_HOLDTM = "rgba(63,191,191,1.0)";//手動更新抑止期間の色
const COLOR_INT_RELOAD = "rgba(191,63,191,1.0)";//強制自動リロード10秒前の色
//ヘルプボタンの色
const COLOR_HLP_DISABL = "rgba(127,127,127,0.5)";//初期値(非稼働)
const COLOR_HLP_UPDATE = "rgba(191,63,63,0.5)";//自動更新トリガ時の色
const COLOR_HLP_UPSOON = "rgba(191,191,63,0.5)";//自動更新トリガまで10秒以内の色
const COLOR_HLP_ACTIVE = "rgba(63,191,63,0.5)";//自動更新モード有効時の色
const COLOR_HLP_PAUSED = "rgba(63,63,191,0.5)";//自動更新の一時停止状態の色
const COLOR_HLP_HOLDTM = "rgba(63,191,191,0.5)";//手動更新抑止期間の色
const COLOR_HLP_RELOAD = "rgba(191,63,191,0.5)";//強制自動リロード10秒前の色
//短周期タイマ変更ボタンの色
const COLOR_ALW_UPDATE = "rgba(191,63,63,0.5)";//短周期タイマ常時稼動モード状態で自動更新トリガ時の色
const COLOR_ALW_UPSOON = "rgba(191,191,63,0.5)";//短周期タイマ常時稼動モード状態で自動更新トリガまで10秒以内の色
const COLOR_ALW_ACTIVE = "rgba(63,191,63,0.5)";//短周期タイマ常時稼動モード状態で自動更新モード有効時の色
const COLOR_ALW_PAUSED = "rgba(63,63,191,0.5)";//短周期タイマ常時稼動モード状態で自動更新の一時停止状態の色
const COLOR_ALW_HOLDTM = "rgba(63,191,191,0.5)";//短周期タイマ常時稼動モード状態で手動更新抑止期間の色
const COLOR_ALW_RELOAD = "rgba(191,63,191,0.5)";//短周期タイマ常時稼動モード状態で強制自動リロード10秒前の色
const COLOR_IDL_DISABL = "rgba(127,127,127,0.5)";//短周期タイマの一時停止状態の色
const COLOR_IDL_UPDATE = "rgba(191,63,63,1.0)";//短周期タイマ適宜停止モード状態で自動更新トリガ時の色
const COLOR_IDL_UPSOON = "rgba(191,191,63,1.0)";//短周期タイマ適宜停止モード状態で自動更新トリガまで10秒以内の色
const COLOR_IDL_ACTIVE = "rgba(63,191,63,1.0)";//短周期タイマ適宜停止モード状態で自動更新モード有効時の色
const COLOR_IDL_PAUSED = "rgba(63,63,191,1.0)";//短周期タイマ適宜停止モード状態で自動更新の一時停止状態の色
const COLOR_IDL_HOLDTM = "rgba(63,191,191,1.0)";//手動更新抑止期間の色短周期タイマ適宜停止モード状態で
const COLOR_IDL_RELOAD = "rgba(191,63,191,1.0)";//短周期タイマ適宜停止モード状態で強制自動リロード10秒前の色
//自動更新ON/OFFボタンの色
const COLOR_AUT_DISABL = "rgba(127,127,127,0.5)";//自動更新OFF時の色
const COLOR_AUT_UPDATE = "rgba(191,63,63,1.0)";//自動更新ON時で自動更新トリガ時の色
const COLOR_AUT_UPSOON = "rgba(191,191,63,1.0)";//自動更新ON時で自動更新トリガまで10秒以内の色
const COLOR_AUT_ACTIVE = "rgba(63,191,63,1.0)";//自動更新ON時で自動更新モード有効時の色
const COLOR_AUT_PAUSED = "rgba(63,63,191,1.0)";//自動更新ON時で自動更新の一時停止状態の色
const COLOR_AUT_HOLDTM = "rgba(63,191,191,1.0)";//自動更新ON時で手動更新抑止期間の色
const COLOR_AUT_RELOAD = "rgba(191,63,191,1.0)";//自動更新ON時で強制自動リロード10秒前の色
//チェックボックスの不透明度
const CHECKBOX_ENABLE_OPACITY = "0.5";
const CHECKBOX_DISABLE_OPACITY = "0.0";
//既読ポイントとしてチェックしたアーティクルの背景色
const DEF_READ_COLOR_ENABLED1 = "rgba(255,255,255,0.1)";
const DEF_READ_COLOR_ENABLED2 = "rgba(255,255,255,0.2)";
const DEF_READ_COLOR_ENABLED3 = "rgba(255,255,255,0.3)";
var READ_COLOR_ENABLED = [];//※ここは変更しない
var READ_COLOR_ENABLED1 = [];//※ここは変更しない
var READ_COLOR_ENABLED2 = [];//※ここは変更しない
var READ_COLOR_ENABLED3 = [];//※ここは変更しない
var READ_COLOR_ENABLED4 = [];//※ここは変更しない
//既読ポイント背景色の切り替えタイプ数
const gi_readColorPattern = 8;//※(READ_COLOR_ENABLED1,2,3,4)の配列要素数を設定
//既読ポイント背景色の繰り返しパターンType数(READ_COLOR_ENABLED1,2,3,4)
const READ_COLOR_CYCLE = 4;//Type数 ※ここは変更しない
//既読ポイント背景色パターンType1
READ_COLOR_ENABLED1 = [
DEF_READ_COLOR_ENABLED1,
DEF_READ_COLOR_ENABLED1,
DEF_READ_COLOR_ENABLED1,
DEF_READ_COLOR_ENABLED1,
DEF_READ_COLOR_ENABLED1,
DEF_READ_COLOR_ENABLED1,
DEF_READ_COLOR_ENABLED1,
DEF_READ_COLOR_ENABLED1,
];
//既読ポイント背景色パターンType2
READ_COLOR_ENABLED2 = [
DEF_READ_COLOR_ENABLED2,
"rgba(255,191,191,0.2)",
"rgba(191,255,191,0.2)",
"rgba(191,191,255,0.2)",
DEF_READ_COLOR_ENABLED2,
"rgba(191,255,255,0.2)",
"rgba(255,191,255,0.2)",
"rgba(255,255,191,0.2)",
];
//既読ポイント背景色パターンType3
READ_COLOR_ENABLED3 = [
DEF_READ_COLOR_ENABLED3,
"rgba(191,255,255,0.3)",
"rgba(255,191,255,0.3)",
"rgba(255,255,191,0.3)",
DEF_READ_COLOR_ENABLED3,
"rgba(255,191,191,0.3)",
"rgba(191,255,191,0.3)",
"rgba(191,191,255,0.3)",
];
//既読ポイント背景色パターンType4
READ_COLOR_ENABLED4 = [
DEF_READ_COLOR_ENABLED3,
DEF_READ_COLOR_ENABLED2,
DEF_READ_COLOR_ENABLED3,
DEF_READ_COLOR_ENABLED2,
DEF_READ_COLOR_ENABLED3,
DEF_READ_COLOR_ENABLED2,
DEF_READ_COLOR_ENABLED3,
DEF_READ_COLOR_ENABLED2,
];
//既読ポイント背景色パターン以降がある場合 パターン以降先頭要素で繰り返し=0, パターン全体を繰り返す=1
const READ_COLOR_CYCLEMODE = 1;
if( ! READ_COLOR_CYCLEMODE ){
//既読ポイント背景色パターン以降がある場合 パターン以降先頭要素で繰り返し
for( gi_defIdx=gi_readColorPattern; gi_defIdx < gi_readArticles; gi_defIdx++ ){
READ_COLOR_ENABLED1[gi_defIdx] = DEF_READ_COLOR_ENABLED1;
READ_COLOR_ENABLED2[gi_defIdx] = DEF_READ_COLOR_ENABLED2;
READ_COLOR_ENABLED3[gi_defIdx] = DEF_READ_COLOR_ENABLED3;
READ_COLOR_ENABLED4[gi_defIdx] = DEF_READ_COLOR_ENABLED3;
}
}else{
//既読ポイント背景色パターン以降がある場合 パターン全体を繰り返す
for( gi_defIdx=gi_readColorPattern; gi_defIdx < gi_readArticles; gi_defIdx++ ){
READ_COLOR_ENABLED1[gi_defIdx] = READ_COLOR_ENABLED1[gi_defIdx % gi_readColorPattern];
READ_COLOR_ENABLED2[gi_defIdx] = READ_COLOR_ENABLED2[gi_defIdx % gi_readColorPattern];
READ_COLOR_ENABLED3[gi_defIdx] = READ_COLOR_ENABLED3[gi_defIdx % gi_readColorPattern];
READ_COLOR_ENABLED4[gi_defIdx] = READ_COLOR_ENABLED4[gi_defIdx % gi_readColorPattern];
}
}
//情報表示部の固定サイズ(フォントサイズを変更したらここも合わせて変更する)
const DISPINFO_WIDTH = "120px";
const DISPINFO_HEIGHT = "22px";
//情報表示部のフォントサイズ unknown,home,list,user,notification,search
const gstrA_titleSize = ["12px","12px","12px","12px","12px","12px"]
//更新時間変更ボタン・自動更新停止ボタンのフォントサイズ unknown,home,list,user,notification,search
const gstrA_buttonSize = ["14px","14px","14px","14px","14px","14px"]
//ホームTLの「フォロー中」表示を置き換える文字列(置き換えない場合は空文字 "" にしておく)
const HOME_TL_NAME = "HomeTL";
//ボタンコントロールの文字列
var BTN_TXT_AUT = "◆";/* 自動更新強制OFF切り替えボタン */
var BTN_TXT_SRT = "▲";/* 短周期タイマの動作切り替えボタン */
var BTN_TXT_INT = "■";/* 更新間隔変更ボタン */
var BTN_TXT_HLP = "?";/* ヘルプダイアログ表示ボタン */
var BTN_TXT_ED1 = "↑";/* エディット欄表示切り替えボタン:表示ON中 */
var BTN_TXT_ED0 = "↓";/* エディット欄表示切り替えボタン:表示OFF中 */
//表示部固定文字列
const TXT_COUNTDOWNTIM = "[ #### / $$$$$$$$ ]";//自動更新有効時のカウントダウン表示
const TXT_PAUSEDUPDATE = "[ Paused Refresh ]";//自動更新停止中
const TXT_PAUSEDUPDAT2 = "[ Paused / $$$$$$$$]";//自動更新停止中(最終更新時間表示あり)
const TXT_MANUALUPDATE = "[ Manually Update. ]";//手動更新実施中
const TXT_AUTOCLICKMOR = "[ AutoClick Update ]";//さらに表示の自動クリック更新実施中
const TXT_RELOADEXTEND = "[ Reload Extended. ]";//強制リロード時間延長
const TXT_FORCERELOADD = "[ Force ReloadPage ]";//強制リロード実施中
const TXT_CHANGEBGTYPE = "[ Change BG Type#. ]";//既読マーク背景パターン変更
const TXT_CHANGEBGNONE = "[ ReadMarkDisabled ]";//既読マーク無効
const TXT_CLEARNEWNOTI = "[ Clear New Info...]";//通知ページの新着表示クリア中
/********************************************
以下のconst定義は各自の変更を推奨しないもの
*******************************************/
//スクロール位置をトップと判定する範囲
const SCROLL_LIMIT = 5.0;
//初期化が必要=0, 初期化済み=1
var gi_initComplete = 0;
//前回処理URL
var gstr_lastURL = null;
//更新間隔カウンタ
var gi_updateCountMs = 0;
//監視間隔タイマの間隔(ミリ秒)
const gi_timerIntervalMs = 1000;
//短周期タイマオブジェクト
var gtmr_shortTimer = null;
//自動更新が停止中
var gi_displayPaused = 0;
//スクロール位置の前回値
var gf_lastYOffset = 0;
//表示中のページ種別 0:unknown, 1:Home, 2:List, 3:User, 4:Notification, 5:Search
var gi_dispMode = 0;
//メディアサイズ 0:非表示, 1:最小サムネイル, 2:通常のコンパクトサムネイル, 3:元のまま
const gi_defaultMediaSize = 2;
var gi_mediaSize = gi_defaultMediaSize;
const MEDIA_NONE = 0;
const MEDIA_SMALL = 1;
const MEDIA_NORMAL = 2;
const MEDIA_LARGE = 3;
const SIZE_NAME = ["0:非表示","1:縮小(小)","2:縮小(中)","3:元サイズ"];
//RTと引用RT非表示設定 制限無し=0, RT非表示=1, 引用RT非表示=2, RT/引用RT両方非表示=3
const gi_defaultNotDispRt = 0;
var gi_notDispRt = gi_defaultNotDispRt;
const NOTRT_NAME = ["0:RT=ON/QUOTE=ON","1:RT=OFF/QUOTE=ON","2:RT=ON/QUOTE=OFF","3:RT=OFF/QUOTE=OFF"];
//このスクリプト固有のプリフィクス(カスタムCSSのセレクタで使用される)
const gstr_scrModeAttrPfx = "PSEUDOTWEETDECK";
//このスクリプト固有のメディアサイズ記録用属性名(カスタムCSSのセレクタで使用される)
const gstr_scrMediaAttr = "PTD_MEDIA";
//このスクリプト固有のRT表示切り替え用属性名(カスタムCSSのセレクタで使用される)
const gstr_scrNotRtAttr = "PTD_NOTRT";
//このスクリプト固有の引用RT表示切り替え用属性名(カスタムCSSのセレクタで使用される)
const gstr_scrNotQuoteAttr = "PTD_NOTQUOTE";
//スクリプト固有のモード記録用属性名
const gstr_scrTypeAttr = "PTD_TYPE";
//スクリプト固有の固定ツイート判定用属性名
const gstr_scrFixedUserAttr = "PTD_FIXED";
//スクリプト固有の既読ポイント判定用チェックボックス属性名
const gstr_scrReadPointAttr = "PTD_READ";
//スクリプト固有の既読ポイント判定用チェックボックス格納親属性名
const gstr_scrReadPointParentAttr = "PTD_READ_PARENT";
//新着表示部のイベントトラップ目印用属性名
const gstr_scrNewTweetAttr = "PTD_NEWTWEET";
//重複するRT非表示時に追加しておく属性
const gstr_multipleArticleAttr = "PTD_MULTI_RT";
//最後に更新をかけた時間
var gdt_lastTriggerTime = new Date();
//ログを取る場合などの種別プリフィクス用文字列
const gstrA_modeNamePrifix = ["NULL","HOME","LIST","USER","NOTI","SEAR"];
//モードのインデックス(配列タイプで定義している他の項目に影響するので変更禁止)
const MODE_NULL = 0;
const MODE_HOME = 1;
const MODE_LIST = 2;
const MODE_USER = 3;
const MODE_NOTI = 4;
const MODE_SEAR = 5;
//自動更新の情報表示エレメント
var gelm_dispInfo = null;
//ボタンコントロールのエレメント
var gelm_allParent = null;
var gelm_btnParent = null;
var gelm_btnShort = null;
var gelm_btnInterval = null;
var gelm_btnAutoOff = null;
var gelm_btnHelp = null;
var gelm_btnEdit = null;
//MutationObserverでDOM更新が上がってきた最終タイムスタンプ保持
var gdt_lastDomTime = new Date();
var gstr_lastDomTime = toFormatedTimeString(gdt_lastDomTime);
//短周期タイマ開始時間を保持
var gstr_lastShortStart = null;
//更新情報の表示エレメント、定周期で再利用するオブジェクト変数のグローバル化
var gelm0 = null;
var gelm1 = null;
var gelm2 = null;
var gelm3 = null;
var gelm4 = null;
var gelm5 = null;
var gelm6 = null;
var gelm7 = null;
var gelm8 = null;
var gelm9 = null;
var gdt_temp = null;
var gb_flgClearNotification = false;
var gtmr_waitClear = null;
//localStorage保存キーのプリフィクス
const FORCEUPDATE_HEADER = "PTD_FTIME";
const INTERVAL_HEADER = "PTD_INTE-";
const MANUAL_HEADER = "PTD_MANU-";
const RELOAD_HEADER = "PTD_RELD-";
const AUTOOFF_HEADER = "PTD_AOFF-";
const IDLETM_HEADER = "PTD_IDLE-";
const CHKCOLOR_HEADER = "PTD_CCOL-";
const EDITDISP_HEADER = "PTD_EDITD";
const NEWTWDISP_HEADER = "PTD_NEWTW";
const MEDIA_HEADER = "PTD_MEDI-";
const NOTRT_HEADER = "PTD_NORT-";
var READ_HEADER = [];
for( gi_defIdx=0; gi_defIdx < 100; gi_defIdx++ ){
READ_HEADER[gi_defIdx] = "PTD_RD" + ("0" + gi_defIdx).slice(-2) + "-";
}
//強制リロードまでの時間管理のため起動した時間を記録
window.localStorage.setItem(FORCEUPDATE_HEADER, ("" + toFormatedDateString(gdt_lastDomTime)) );
//操作ボタンコントロールのID
const PARENT_BLOCK = "PTD_PARENT_BLOCK";
const BUTTON_BLOCK = "PTD_BUTTON_BLOCK";
const INFO_BLOCK = "PTD_INFO_BLOCK"
const HELP_BLOCK = "PTD_HELP_BLOCK"
const SHORT_BLOCK = "PTD_SHORT_BLOCK";
const INTERVAL_BLOCK = "PTD_INTERVAL_BLOCK";
const AUTO_BLOCK = "PTD_AUTO_BLOCK";
const EDITBTN_BLOCK = "PTD_EDIT_BLOCK";
//ポップアップ部コントロールのID
const POPUP_BLOCK = "PTD_POPUP_BLOCK";
//ポップアップ終了時間要素
const POPUP_ENDTIME = "PTD_POPUP_ENDTIME_BLOCK";
//コンフィグ画面コントロールID
const SETTING_BLOCK = "PTD_SETTING_CONIG_BLOCK";
var gb_enableSettingWindow = false;
//エディット部表示非表示切り替え時の追加要素
const EDITSW_BLOCK = "PTD_EDIT_SWITCH_BLOCK";
//タイムスタンプ部にチェックボックス追加済みを示す追加要素
const TIME_FIXED = "PTD_TIME_FIXED_BLOCK";
//画像リンク部のclickを乗っ取った状態の追加要素
const IMAGE_LINK = "PTD_IMAGE_LINK";
//表示部・ボタン類の色替え
var gi_colorType = 0;
const TYPE_UPDATE = 1;
const TYPE_UPSOON = 2;
const TYPE_ACTIVE = 3;
const TYPE_PAUSED = 4;
const TYPE_HOLDTM = 5;
const TYPE_RELOAD = 6;
//チェックボックスエレメントに追加するタイムスタンプの要素名
const CHK_TIMESTAMP = "PTD_CHK_TIMESTAMP";
//チェックされたアーティクルのタイムスタンプ
var gstrA_readTimeStamp = [];
//チェックされたアーティクルのURL
var gstrA_readArticleURL = [];
for( gi_defIdx=0; gi_defIdx < gi_readArticles; gi_defIdx++ ){
gstrA_readTimeStamp[gi_defIdx] = "";
gstrA_readArticleURL[gi_defIdx] = "";
}
//チェックされたアーティクルの背景色モード ※非表示モードの時=-1
var gi_readCheckedColorMode = 0;
//新着が消えるのを待ち合わせるカウンタ
var gi_chkNotificationCount = 0;
const gi_chkNotificationCountMax = 100;
//ダイアログ表示の余白
const CRLF = "\r\n";
const SPC = "
\r\n ";
const SPT = " ";
//対象URLの基本部
const TWITTER_URL = "https://twitter.com/";
const TWITTER_URL2 = "https://twitter.com";
//TwitterURLのパス文字列
const PATH_HOME = "home";
const PATH_LIST = "i/lists/";
const PATH_NOTI = "notifications";
const PATH_SEAR = "search";
//本スクリプトとは無関係のURLかどうかを判定 ※先にPATH_LISTかどうかを判定しないとリスト一覧の i なしlistsにパターンマッチしてしまうので注意
function isOtherURL(hr){
if( hr.indexOf(TWITTER_URL + "messages") != -1 ||
hr.indexOf(TWITTER_URL + "compose") != -1 ||
hr.indexOf(TWITTER_URL + "settings") != -1 ||
hr.indexOf(TWITTER_URL + "explore") != -1 ||
hr.indexOf(TWITTER_URL + "i/bookmarks") != -1 ||
hr.indexOf(TWITTER_URL + "i/circles") != -1 ||
hr.indexOf(TWITTER_URL + "i/connect_people") != -1 ||
hr.indexOf(TWITTER_URL + "i/display") != -1 ||
hr.indexOf(TWITTER_URL + "intent/") != -1 ||
hr.indexOf(TWITTER_URL + "ja/") != -1 ||
hr.indexOf(TWITTER_URL + "en/") != -1 ||
(hr.indexOf(TWITTER_URL) != -1 && hr.indexOf("/status/") != -1) ||
(hr.indexOf(TWITTER_URL) != -1 && hr.indexOf("/lists") != -1)){
return true;
}
return false;
}
//日付時刻の整形
function toFormatedDateString(date){
// yy/mm/dd HH:MM:SS
var ret = ("0" + date.getFullYear()).slice(-2) + "/" +
("0" + (date.getMonth() + 1)).slice(-2) + "/" +
("0" + date.getDate()).slice(-2) + " " +
("0" + date.getHours()).slice(-2) + ":" +
("0" + date.getMinutes()).slice(-2) + ":" +
("0" + date.getSeconds()).slice(-2);
return ret;
}
//時刻の整形
function toFormatedTimeString(date){
// HH:MM:SS
var ret = ("0" + date.getHours()).slice(-2) + ":" +
("0" + date.getMinutes()).slice(-2) + ":" +
("0" + date.getSeconds()).slice(-2);
return ret;
}
/*
//ログファイルの先頭プリフィクス "R","G","B" などの文字列を設定、ログ出力なしならnullにする (filePrx判定すら重くなる原因なので不使用時はコメントアウトしておきます)
var filePfx = null;
//var filePfx = "G";
//一般ファイル吐き出しタイプのログ(ダウンロード処理によって代替するのでダウンロードフォルダへの自動保存設定である必要あり、とても重い)
function logSave(text) {
var date = (new Date(Date.now()+9*3600*1000)).toISOString();
var name = filePfx + date.replace(/\.\d+|[^\d]/g, "") + ("000" + new Date().getMilliseconds()).slice(-3) + ".log";
var writeText = name + " / " + text;
var blob = new Blob( [writeText], {type: "text/plain"} );
var link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = name;
link.click();
console.log("☆LogOutput : " + name + " / " + writeText);
}
*/
//更新が必要かどうかをURLとフォーカスコントロールの状態などから判定(内部の画面遷移とlocation.hrefは一致しないタイミングがあるので更新直前に確認が必要)
function shouldNotUpdate() {
var searchCandidate;
var focusElement;
var focusAttr;
//HOME
if( gi_dispMode == MODE_HOME ){
searchCandidate = document.body.querySelectorAll('div[class="css-1dbjc4n r-13awgt0 r-bnwqim"]');
focusElement = document.activeElement;
if(searchCandidate.length > 0) {
if(searchCandidate[0].innerHTML != ""){
//更新してしまうと検索ボックスが閉じてしまうため、この場合は更新しない
//console.log("※SearchBox Enable");
return true;
}
}
if(window.location.href == TWITTER_URL + PATH_HOME ){
//ツイート入力などにフォーカスが当たっている場合には処理しないようにする(フォーカスが外れる)
focusAttr = focusElement.getAttribute("data-testid");
if(focusAttr !== null){
if(focusAttr != "tweet" && focusAttr != "retweet" && focusAttr != "unretweet" &&
focusAttr != "like" && focusAttr != "unlike" && focusAttr != "AppTabBar_Home_Link"){
//ホームボタンを押すと、ツイートにフォーカスが設定されることがある。その場合は更新する。
//console.log("※InputBox etc Enable + [" + focusAttr + "]");
return true;
}else{
//console.log("※Focus Attr + [" + focusAttr + "]");
}
}
if( gi_modeAutoOff == 1 ){
return true;
}else{
return false;
}
}else{
return true;
}
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return true");
return true;
}
//LIST
if( gi_dispMode == MODE_LIST ){
if(window.location.href.indexOf(TWITTER_URL + PATH_LIST) != -1 ){
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return false");
if( gi_modeAutoOff == 1 ){
return true;
}else{
return false;
}
}
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return true");
return false;
}
//USER
if( gi_dispMode == MODE_USER ){
var hr = window.location.href;
if(hr == (TWITTER_URL + PATH_HOME) ||
hr.indexOf(TWITTER_URL + PATH_LIST) != -1 ||
hr.indexOf(TWITTER_URL + PATH_NOTI) != -1 ||
hr.indexOf(TWITTER_URL + PATH_SEAR) != -1 ||
isOtherURL(hr) ){
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return false");
return true;
}
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return true");
if( gi_modeAutoOff == 1 ){
return true;
}else{
return false;
}
}
//NOTI
if( gi_dispMode == MODE_NOTI ){
if(window.location.href.indexOf(TWITTER_URL + PATH_NOTI) != -1 ){
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return false");
return false;
}
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return true");
return true;
}
//SEAR
if( gi_dispMode == MODE_SEAR ){
focusElement = document.activeElement;
focusAttr = focusElement.getAttribute("data-testid");
if(focusAttr !== null){
//検索ボックスにフォーカスがあったら更新させない
if(focusAttr == "SearchBox_Search_Input"){
//console.log("※InputBox Enable + [" + focusAttr + "] return true");
return true;
}else{
//console.log("※Focus Attr + [" + focusAttr + "]");
}
}
if(window.location.href.indexOf(TWITTER_URL + PATH_SEAR) != -1 ){
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return false");
if( gi_modeAutoOff == 1 ){
return true;
}else{
return false;
}
}
//console.log("※Current href + [" + window.location.href + "] / Focus tagName + [" + focusElement.tagName + "] return true");
return true;
}
return true;
}
//定周期更新処理メイン
function updateTimeline() {
gdt_temp = new Date();
//画面遷移を判定し、変わっていたら初期処理をやりなおす
if( gstr_lastURL != window.location.href ){
gstr_lastURL = window.location.href;
gi_initComplete = 0;
for(var idx=0; idx < gi_readArticles; idx++){
gstrA_readTimeStamp[idx] = "";
gstrA_readArticleURL[idx] = "";
}
if(gi_idleShortTimer){
//停止していた短周期タイマを再開
if( gtmr_shortTimer === null ){
gtmr_shortTimer = window.setInterval(replaceEtements, gi_shortIntervalMs);
//console.log("★gtmr_shortTimer: START[clearElements]");
}
gstr_lastShortStart = gdt_temp;
}
//初期処理
clearElements();
//URLに対応する設定をローカルストレージから読み込む
findSettings();
//既読ポイント背景色設定の読込
if( gi_enableReadPointCheckBox ){
loadReadPointColorSetting();
}
return;
}
//自動更新に該当しないページは何もせず戻る
if( gi_dispMode == MODE_NULL ){
return;
}
if(gi_idleShortTimer){
//短周期タイマ開始から時間が経過したらタイマを停止させる
if( gtmr_shortTimer !== null ){
if( ( gdt_temp.getTime() - gstr_lastShortStart.getTime() ) / (gi_shortTimerIdleMs ) > 1.0 ){
window.clearInterval(gtmr_shortTimer);
gtmr_shortTimer = null;
//console.log("★gtmr_shortTimer: OFF");
}
}else{
//停止していた短周期タイマをワンショット実行
var tmp = document.title;
if( tmp.indexOf("@") == 0 || tmp.slice(-3) == "/ X" ){
replaceEtements();
}
}
if(window.pageYOffset != gf_lastYOffset){
//先頭に戻った場合ワンショットで短周期処理を走らせる
if( window.pageYOffset == 0 ){
replaceEtements();
}
//スクロール操作中短周期処理を再開させる
if( Math.abs(window.pageYOffset - gf_lastYOffset) > SCROLL_LIMIT ){
if( gtmr_shortTimer === null ){
gtmr_shortTimer = window.setInterval(replaceEtements, gi_shortIntervalMs);
}
gstr_lastShortStart = gdt_temp;
}
gf_lastYOffset = window.pageYOffset;
}
}
//console.log("☆PageY-Offset=" + window.pageYOffset);
if(window.pageYOffset <= SCROLL_LIMIT) {
if(!shouldNotUpdate()) {
if(gi_updateCountMs >= giA_updateIntervalMs[gi_dispMode]) {
//フォーカス判定が外れた状態からの復帰
if( gi_initComplete == 0 ){
clearElements();
}
if(gi_reloadTimeoutSec){
//一定時間以上DOM更新が無い場合はリロードする
if( ( gdt_temp.getTime() - gdt_lastDomTime.getTime() ) > (gi_reloadTimeoutSec * 1000) ){
var f = false;
var v = "20" + window.localStorage.getItem(FORCEUPDATE_HEADER);
if( v != null ){
var timeSub = (gdt_temp.getTime() - (new Date(v)).getTime() );
//短時間に実施しないため前回実施時刻を獲得
if( timeSub > (gi_forceUpdateLockTimeSec * 1000) && ! gb_enableSettingWindow ){
f = true;
}else{
gi_updateCountMs = Math.trunc(Math.random() * giA_updateIntervalMs[gi_dispMode] / 1000) * 1000;
forceUpdateColor(COLOR_RELOAD, TXT_RELOADEXTEND);
return;
}
}else{
f = true;
}
if( f ){
//if(filePfx!==null) logSave( gstrA_modeNamePrifix[gi_dispMode] + " RELOAD [" + ("000" + reloadCount).slice(-3) + "] " + gstr_lastDomTime );
window.localStorage.setItem(FORCEUPDATE_HEADER, ("" + toFormatedDateString(gdt_temp)) );
dispPopupMessage("リロードします", 10);
window.setTimeout( function(){ window.location.reload(); }, gi_reloadWaitMs );
gi_displayPaused = 0;
gi_updateCountMs = 0;
forceUpdateColor(COLOR_UPDATE, TXT_FORCERELOADD);
gi_initComplete = 0;
return;
}
}
}
//更新トリガ(通知ページの新着クリアは経過時間に関係なくトリガする)
if( gdt_temp.getTime() - gdt_lastTriggerTime.getTime() > gi_manualUpdateIntervalSec * 1000 || gi_dispMode == MODE_NOTI ){
execTrigger();
}
if(gi_idleShortTimer){
//停止していた短周期タイマをワンショット実行
if( gtmr_shortTimer === null ){
replaceEtements();
}
}
//更新されたのでカウンタをリセット
gi_displayPaused = 0;
gi_updateCountMs = 0;
//console.log("☆Counter Update0 [" + gi_updateCountMs + "]" );
}else{
if(gi_idleShortTimer && gi_displayPaused){
//停止していた短周期タイマを時差でワンショット実行
if( gtmr_shortTimer === null ){
window.setTimeout( replaceEtements, gi_timerIntervalMs );
}
}
//更新待ちカウンタの加算
gi_displayPaused = 0;
gi_updateCountMs += gi_timerIntervalMs;
//console.log("☆Counter Update1 [" + gi_updateCountMs + "]" );
}
}else{
//フォーカスの判定が外れたのでカウントリセット・URLが変わっていたので次回オブジェクト捜索しなおし
gi_initComplete = 0;
gi_updateCountMs = giA_updateIntervalMs[gi_dispMode];
gi_displayPaused = 1;
//console.log("☆Wait for current control [" + gi_updateCountMs + "]" );
}
}else{
//先頭に戻された次回に少し待って更新がかかるようにする
gi_displayPaused = 1;
//手動更新の操作でトリガが掛かった後ならカウンタリセット、それ以外でスクロール位置が先頭に戻ったら少し後にトリガ
if( gdt_temp.getTime() - gdt_lastTriggerTime.getTime() > gi_manualUpdateIntervalSec * 1000 ){
gi_updateCountMs = giA_updateIntervalMs[gi_dispMode] - gi_onTopWaitMs;
}else{
gi_updateCountMs = 0;
}
if(gi_updateCountMs < 1000 ) gi_updateCountMs = 0;
//console.log("☆Wait for window top [" + gi_updateCountMs + "]" );
}
//更新に関する情報を表示する
updateDisplayInfo();
}
//更新トリガ処理
function execTrigger(){
var e0, e1, tm = new Date();
if( gi_dispMode == MODE_HOME ){
//メニューのHomeを押す事で更新トリガさせる
var homeButton = document.body.querySelectorAll('a[data-testid="AppTabBar_Home_Link"]');
if(homeButton.length > 0) {
homeButton[0].click();
//更新トリガの時間を記録
gdt_lastTriggerTime = tm;
//if(filePfx!==null) logSave(gstrA_modeNamePrifix[gi_dispMode] + " CLICK [" + ("000" + reloadCount).slice(-3) + "] " + gstr_lastDomTime );
//console.log("★Home Button Update");
}
}else if( gi_dispMode == MODE_LIST || gi_dispMode == MODE_SEAR || gi_dispMode == MODE_USER ){
//スクロール操作によって更新トリガさせる
window.scrollTo(0, window.innerHeight);
window.setTimeout( function(){ window.scrollTo(0, 0);}, 0 );
//更新トリガの時間を記録
gdt_lastTriggerTime = tm;
//if(filePfx!==null) logSave(gstrA_modeNamePrifix[gi_dispMode] + " @" + (window.location.href.slice(28) + " ").substr(0,19) + " SCROLL [" + ("000" + reloadCount).slice(-3) + "] " + gstr_lastDomTime );
//console.log("★Scroll Update");
/*
//参考ソース https://github.com/natsuyasai/TwitterAutoReloadScript
// aタグの中からタグ要素かつ現在アクティブになっている要素を取得し、クリックイベントを発火させる・・・手動で上部タブをクリックしても更新かかってくれませんね、これは旧仕様用でしょう
e0 = document.querySelectorAll('a[role="tab"][aria-selected="true"]');
if( e0.length > 0 ) {
e0[0].click();
}
*/
}else if( gi_dispMode == MODE_NOTI ){
//通知ページの場合は新着表示クリア
clearNewNotification();
}
}
//表示用エレメントのチェック〜無ければ捜索
function findDisplayElements(){
//カウンタ表示用のエレメントを捜索
if( gelm_dispInfo === null ){
if( gi_dispMode == MODE_HOME ){
//Home
gelm0 = document.querySelectorAll('a[role="tab"][aria-selected="true"]');
if( gelm0.length > 0 ){
gelm1 = gelm0[0].firstElementChild;
if( gelm1 !== null ){
gelm2 = gelm1.firstElementChild;
if( gelm2 !== null ){
//情報表示&ボタン類を追加する場所
setupElement(gelm2);
//「フォロー中」を「Home」に置換
gelm3 = gelm2.firstElementChild;
if( gelm3 !== null && HOME_TL_NAME != "" ){
gelm3.textContent = HOME_TL_NAME;
}
//情報表示をする場所
//gelm_dispInfo = gelm2.firstElementChild;
//console.log("★find: Element");
}
}
}
}else if( gi_dispMode == MODE_LIST ){
//List
//リスト作成者のアカウント名に表示項目を追加
gelm0 = document.querySelectorAll('h2[dir="ltr"][aria-level="2"][role="heading"]');
if( gelm0.length > 0 ){
gelm4 = gelm0[0].firstElementChild;
if( gelm4 !== null ){
//情報表示&ボタン類を追加する場所
setupElement(gelm4);
}
}
}else if( gi_dispMode == MODE_USER ){
//User
//ユーザーのツイート数に表示項目を追加
gelm0 = document.querySelectorAll('h2[dir="ltr"][aria-level="2"][role="heading"]');
if( gelm0.length > 0 ){
gelm4 = gelm0[0].firstElementChild;
if( gelm4 !== null ){
gelm5 = gelm4.firstElementChild;
if( gelm5 !== null ){
//情報表示&ボタン類を追加する場所
setupElement(gelm5);
}
}
//console.log("★find: Element");
}
}else if( gi_dispMode == MODE_NOTI ){
//Notification
gelm0 = document.querySelectorAll('h2[dir="ltr"][aria-level="2"][role="heading"]');
if( gelm0.length > 0 ){
setupElement(gelm0[0]);
gelm_btnAutoOff.style.display = "none";
//console.log("★find: Element");
}
}else if( gi_dispMode == MODE_SEAR ){
//Search
//検索ページの最新に表示項目を追加
gelm0 = document.querySelectorAll('div[data-testid="ScrollSnap-SwipeableList"]');
if( gelm0.length > 0 ){
gelm1 = gelm0[0].firstElementChild;
if( gelm1 !== null ){
gelm2 = gelm1.firstElementChild;
if( gelm2 !== null ){
gelm3 = gelm2.nextElementSibling;
if( gelm3 !== null ){
gelm4 = gelm3.firstElementChild;
if( gelm4 !== null ){
gelm5 = gelm4.firstElementChild;
if( gelm5 !== null ){
gelm6 = gelm5.firstElementChild;
if( gelm6 !== null ){
//情報表示&ボタン類を追加する場所
setupElement(gelm6);
//console.log("★find: Element");
}
}
}
}
}
}
}
}
}
}
//情報の表示更新〜色替え
function updateDisplayInfo(){
var tmp, str;
//更新に関する情報を表示する
if( gi_initComplete != 0 || gi_displayPaused ){
//表示用エレメントのチェック〜無ければ捜索
findDisplayElements();
//カウンタを更新
if( gelm_dispInfo !== null ){
tmp = giA_updateIntervalMs[gi_dispMode] - gi_updateCountMs;
if(tmp < 1000 ) tmp = 0;
//フォーカスを持ったタブのみカウントを都度更新(全部に対して行うと重すぎる)
//設定内容を設定先と比較して違ったら代入するようにしているのは、代入によって内部でDOM更新が走り処理が重くなるため
if( document.visibilityState === "visible" && document.hasFocus() === true && gi_dispMode != MODE_NOTI ){
if( ! gi_displayPaused ){
//TXT_COUNTDOWNTIM = " [ #### / $$$$$$$$ ]";
str = TXT_COUNTDOWNTIM.replace("####", ("0000" + (tmp / 1000)).slice(-4) ).replace("$$$$$$$$",gstr_lastDomTime)
if(gelm_dispInfo.textContent != str) gelm_dispInfo.textContent = str;
if( tmp == 0 ){
gi_colorType = TYPE_UPDATE;
}else if( tmp <= 10000 ){
//強制リロード間際の色替え
if( gdt_temp.getTime() - gdt_lastDomTime.getTime() > (gi_reloadTimeoutSec * 1000 - 10000) && gi_reloadTimeoutSec > 0 ){
gi_colorType= TYPE_RELOAD;
}else{
gi_colorType = TYPE_UPSOON;
}
}else{
gi_colorType = TYPE_ACTIVE;
}
}else{
if( ! gi_enableTimeAutoOff ){
str = TXT_PAUSEDUPDATE;
}else{
//TXT_PAUSEDUPDAT2 = "[ Paused / $$$$$$$$]";
str = TXT_PAUSEDUPDAT2.replace("$$$$$$$$",gstr_lastDomTime);
}
if(gelm_dispInfo.textContent != str) gelm_dispInfo.textContent = str;
gi_colorType = TYPE_PAUSED;
}
}else{
//最後にDOM更新があがってきたタイムスタンプを表示
if( ! gi_displayPaused || gi_dispMode == MODE_NOTI ){
str = " [Latest / " + gstr_lastDomTime + "]";
if(gelm_dispInfo.textContent != str) gelm_dispInfo.textContent = str;
if( tmp == 0 && gi_dispMode != MODE_NOTI ){
gi_colorType = TYPE_UPDATE;
}else if( tmp <= 10000 && gi_dispMode != MODE_NOTI ){
//強制リロード間際の色替え
if( gdt_temp.getTime() - gdt_lastDomTime.getTime() > (gi_reloadTimeoutSec * 1000 - 10000) && gi_reloadTimeoutSec > 0 ){
gi_colorType= TYPE_RELOAD;
}else{
gi_colorType = TYPE_UPSOON;
}
}else{
//通知ページ専用処理
if( gi_dispMode == MODE_NOTI ){
//強制リロード間際の色替え
if( gdt_temp.getTime() - gdt_lastDomTime.getTime() > (gi_reloadTimeoutSec * 1000 - 10000) && gi_reloadTimeoutSec > 0 ){
gi_colorType= TYPE_RELOAD;
}else if(gb_flgClearNotification){
//新着クリア中の表示
forceUpdateColor(COLOR_WHITE,TXT_CLEARNEWNOTI);
gi_colorType= 0;
}else{
gi_colorType= TYPE_ACTIVE;
}
}else{
gi_colorType = TYPE_ACTIVE;
}
}
}else{
if( ! gi_enableTimeAutoOff ){
str = TXT_PAUSEDUPDATE;
}else{
//TXT_PAUSEDUPDAT2 = "[ Paused / $$$$$$$$]";
str = TXT_PAUSEDUPDAT2.replace("$$$$$$$$",gstr_lastDomTime);
}
if(gelm_dispInfo.textContent != str) gelm_dispInfo.textContent = str;
gi_colorType = TYPE_PAUSED;
}
}
if(gelm_dispInfo.style.fontSize != gstrA_titleSize[gi_dispMode]) gelm_dispInfo.style.fontSize = gstrA_titleSize[gi_dispMode];
//表示部をクリックしても更新トリガしない期間の色替え
if( gi_colorType != TYPE_RELOAD && gi_colorType != 0 ){
if( gdt_temp.getTime() - gdt_lastTriggerTime.getTime() <= gi_manualUpdateIntervalSec * 1000 ){
gi_colorType = TYPE_HOLDTM;
}
}
//ボタンコントロールの色替え
if(gi_colorType == TYPE_UPDATE){
if(gelm_dispInfo.style.color != COLOR_UPDATE) gelm_dispInfo.style.color = COLOR_UPDATE;
if(gelm_btnInterval.style.color != COLOR_INT_UPDATE) gelm_btnInterval.style.color = COLOR_INT_UPDATE;
if(gelm_btnHelp.style.color != COLOR_HLP_UPDATE) gelm_btnHelp.style.color = COLOR_HLP_UPDATE;
if( gi_modeAutoOff == 1 ){
if(gelm_btnAutoOff.style.color != COLOR_AUT_DISABL) gelm_btnAutoOff.style.color = COLOR_AUT_DISABL;
}else{
if(gelm_btnAutoOff.style.color != COLOR_AUT_UPDATE) gelm_btnAutoOff.style.color = COLOR_AUT_UPDATE;
}
//短周期タイマの稼動状態
if( gi_idleShortTimer == 1 ){
if( gtmr_shortTimer === null ){
//短周期タイマ停止中
if(gelm_btnShort.style.color != COLOR_IDL_DISABL) gelm_btnShort.style.color = COLOR_IDL_DISABL;
}else{
//短周期タイマ動作中
if(gelm_btnShort.style.color != COLOR_IDL_UPDATE) gelm_btnShort.style.color = COLOR_IDL_UPDATE;
}
}else{
//短周期タイマ常時稼動モード
if(gelm_btnShort.style.color != COLOR_ALW_UPDATE) gelm_btnShort.style.color = COLOR_ALW_UPDATE;
}
}else if(gi_colorType == TYPE_UPSOON){
if(gelm_dispInfo.style.color != COLOR_UPSOON) gelm_dispInfo.style.color = COLOR_UPSOON;
if(gelm_btnInterval.style.color != COLOR_INT_UPSOON) gelm_btnInterval.style.color = COLOR_INT_UPSOON;
if(gelm_btnHelp.style.color != COLOR_HLP_UPSOON) gelm_btnHelp.style.color = COLOR_HLP_UPSOON;
if( gi_modeAutoOff == 1 ){
if(gelm_btnAutoOff.style.color != COLOR_AUT_DISABL) gelm_btnAutoOff.style.color = COLOR_AUT_DISABL;
}else{
if(gelm_btnAutoOff.style.color != COLOR_AUT_UPSOON) gelm_btnAutoOff.style.color = COLOR_AUT_UPSOON;
}
//短周期タイマの稼動状態
if( gi_idleShortTimer == 1 ){
if( gtmr_shortTimer === null ){
//短周期タイマ停止中
if(gelm_btnShort.style.color != COLOR_IDL_DISABL) gelm_btnShort.style.color = COLOR_IDL_DISABL;
}else{
//短周期タイマ動作中
if(gelm_btnShort.style.color != COLOR_IDL_UPSOON) gelm_btnShort.style.color = COLOR_IDL_UPSOON;
}
}else{
//短周期タイマ常時稼動モード
if(gelm_btnShort.style.color != COLOR_ALW_UPSOON) gelm_btnShort.style.color = COLOR_ALW_UPSOON;
}
}else if(gi_colorType == TYPE_ACTIVE){
if(gelm_dispInfo.style.color != COLOR_ACTIVE) gelm_dispInfo.style.color = COLOR_ACTIVE;
if(gelm_btnInterval.style.color != COLOR_INT_ACTIVE) gelm_btnInterval.style.color = COLOR_INT_ACTIVE;
if(gelm_btnHelp.style.color != COLOR_HLP_ACTIVE) gelm_btnHelp.style.color = COLOR_HLP_ACTIVE;
if( gi_modeAutoOff == 1 ){
if(gelm_btnAutoOff.style.color != COLOR_AUT_DISABL) gelm_btnAutoOff.style.color = COLOR_AUT_DISABL;
}else{
if(gelm_btnAutoOff.style.color != COLOR_AUT_ACTIVE) gelm_btnAutoOff.style.color = COLOR_AUT_ACTIVE;
}
//短周期タイマの稼動状態
if( gi_idleShortTimer == 1 ){
if( gtmr_shortTimer === null ){
//短周期タイマ停止中
if(gelm_btnShort.style.color != COLOR_IDL_DISABL) gelm_btnShort.style.color = COLOR_IDL_DISABL;
}else{
//短周期タイマ動作中
if(gelm_btnShort.style.color != COLOR_IDL_ACTIVE) gelm_btnShort.style.color = COLOR_IDL_ACTIVE;
}
}else{
//短周期タイマ常時稼動モード
if(gelm_btnShort.style.color != COLOR_ALW_ACTIVE) gelm_btnShort.style.color = COLOR_ALW_ACTIVE;
}
}else if(gi_colorType == TYPE_PAUSED){
if(gelm_dispInfo.style.color != COLOR_PAUSED) gelm_dispInfo.style.color = COLOR_PAUSED;
if(gelm_btnInterval.style.color != COLOR_INT_PAUSED) gelm_btnInterval.style.color = COLOR_INT_PAUSED;
if(gelm_btnHelp.style.color != COLOR_HLP_PAUSED) gelm_btnHelp.style.color = COLOR_HLP_PAUSED;
if( gi_modeAutoOff == 1 ){
if(gelm_btnAutoOff.style.color != COLOR_AUT_DISABL) gelm_btnAutoOff.style.color = COLOR_AUT_DISABL;
}else{
if(gelm_btnAutoOff.style.color != COLOR_AUT_PAUSED) gelm_btnAutoOff.style.color = COLOR_AUT_PAUSED;
}
//短周期タイマの稼動状態
if( gi_idleShortTimer == 1 ){
if( gtmr_shortTimer === null ){
//短周期タイマ停止中
if(gelm_btnShort.style.color != COLOR_IDL_DISABL) gelm_btnShort.style.color = COLOR_IDL_DISABL;
}else{
//短周期タイマ動作中
if(gelm_btnShort.style.color != COLOR_IDL_PAUSED) gelm_btnShort.style.color = COLOR_IDL_PAUSED;
}
}else{
//短周期タイマ常時稼動モード
if(gelm_btnShort.style.color != COLOR_ALW_PAUSED) gelm_btnShort.style.color = COLOR_ALW_PAUSED;
}
}else if(gi_colorType == TYPE_HOLDTM){
if(gelm_dispInfo.style.color != COLOR_HOLDTM) gelm_dispInfo.style.color = COLOR_HOLDTM;
if(gelm_btnInterval.style.color != COLOR_INT_HOLDTM) gelm_btnInterval.style.color = COLOR_INT_HOLDTM;
if(gelm_btnHelp.style.color != COLOR_HLP_HOLDTM) gelm_btnHelp.style.color = COLOR_HLP_HOLDTM;
if( gi_modeAutoOff == 1 ){
if(gelm_btnAutoOff.style.color != COLOR_AUT_DISABL) gelm_btnAutoOff.style.color = COLOR_AUT_DISABL;
}else{
if(gelm_btnAutoOff.style.color != COLOR_AUT_HOLDTM) gelm_btnAutoOff.style.color = COLOR_AUT_HOLDTM;
}
//短周期タイマの稼動状態
if( gi_idleShortTimer == 1 ){
if( gtmr_shortTimer === null ){
//短周期タイマ停止中
if(gelm_btnShort.style.color != COLOR_IDL_DISABL) gelm_btnShort.style.color = COLOR_IDL_DISABL;
}else{
//短周期タイマ動作中
if(gelm_btnShort.style.color != COLOR_IDL_HOLDTM) gelm_btnShort.style.color = COLOR_IDL_HOLDTM;
}
}else{
//短周期タイマ常時稼動モード
if(gelm_btnShort.style.color != COLOR_ALW_HOLDTM) gelm_btnShort.style.color = COLOR_ALW_HOLDTM;
}
}else if(gi_colorType == TYPE_RELOAD){
if(gelm_dispInfo.style.color != COLOR_RELOAD) gelm_dispInfo.style.color = COLOR_RELOAD;
if(gelm_btnInterval.style.color != COLOR_INT_RELOAD) gelm_btnInterval.style.color = COLOR_INT_RELOAD;
if(gelm_btnHelp.style.color != COLOR_HLP_RELOAD) gelm_btnHelp.style.color = COLOR_HLP_RELOAD;
if( gi_modeAutoOff == 1 ){
if(gelm_btnAutoOff.style.color != COLOR_AUT_DISABL) gelm_btnAutoOff.style.color = COLOR_AUT_DISABL;
}else{
if(gelm_btnAutoOff.style.color != COLOR_AUT_RELOAD) gelm_btnAutoOff.style.color = COLOR_AUT_RELOAD;
}
//短周期タイマの稼動状態
if( gi_idleShortTimer == 1 ){
if( gtmr_shortTimer === null ){
//短周期タイマ停止中
if(gelm_btnShort.style.color != COLOR_IDL_DISABL) gelm_btnShort.style.color = COLOR_IDL_DISABL;
}else{
//短周期タイマ動作中
if(gelm_btnShort.style.color != COLOR_IDL_RELOAD) gelm_btnShort.style.color = COLOR_IDL_RELOAD;
}
}else{
//短周期タイマ常時稼動モード
if(gelm_btnShort.style.color != COLOR_ALW_RELOAD) gelm_btnShort.style.color = COLOR_ALW_RELOAD;
}
}
}
}
}
//通常パターン以外での色替え(手動の更新操作やエラー発生時などのモニタリング用)
function forceUpdateColor(rgba,txt){
if( gelm_dispInfo === null || gelm_dispInfo.textContent === null || gelm_btnInterval === null ||
gelm_btnHelp === null || gelm_btnAutoOff === null || gelm_btnShort === null ) return;
gelm_dispInfo.textContent = txt;
gelm_dispInfo.style.color = rgba;
gelm_btnHelp.style.color = COLOR_BLACK;
gelm_btnInterval.style.color = COLOR_GRAY;
gelm_btnAutoOff.style.color = COLOR_GRAY;
gelm_btnShort.style.color = COLOR_GRAY;
}
//要素の初回書き換わりを監視
window.addEventListener('load', function(){
gi_initComplete = 0;
//各種カウンタの初期化
gi_updateCountMs = 0;
gi_displayPaused = 0;
//console.log("★load: WindowLoaded");
});
//アーティクル数に応じた可変要素の1つ上のエレメントをDOM更新監視(アーティクルの増減をイベントとして受け取る)
var observer = new MutationObserver(function(){
//DOMの変化が起こった時の処理
gdt_lastDomTime = new Date();
gstr_lastDomTime = toFormatedTimeString(gdt_lastDomTime);
//停止していた短周期タイマを再開
if( gi_idleShortTimer ){
if( gtmr_shortTimer === null ){
gtmr_shortTimer = window.setInterval(replaceEtements, gi_shortIntervalMs);
//console.log("★gtmr_shortTimer: START[DOM]");
}
gstr_lastShortStart = gdt_lastDomTime;
}
//if(filePfx!==null) logSave(gstrA_modeNamePrifix[gi_dispMode] + " OBSERV ");
console.log("★DOMが変化しました " + gdt_lastDomTime.toLocaleTimeString() );
});
//MutationObserver監視時のオプション
const configObserver = {
attributes: false,
characterData: true,
childList: true,
subtree: false,
attributeOldValue: false,
characterDataOldValue: false
};
//監視するエレメントの取得・再取得
async function clearElements(){
//スクリプト固有の属性を一旦削除
gelm0 = document.querySelectorAll('body[' + gstr_scrTypeAttr +']');
if( gelm0.length > 0 ){
gelm0[0].removeAttribute( gstr_scrTypeAttr );
}
//URLからモードを決定
getModeFromURL();
if( gi_dispMode == MODE_NULL ){
gstr_lastURL = "";
window.setTimeout(clearElements, gi_initWaitMs);
return;
}
//カスタムCSSで判別するための要素を追加(ユーザーページは消去法で判定しないと無理で、カスタムCSSではそんな判別は出来ないため)
gelm0 = document.querySelectorAll('body');
if( gelm0.length > 0 ){
gelm0[0].setAttribute( gstr_scrTypeAttr, gstr_scrModeAttrPfx + gstrA_modeNamePrifix[gi_dispMode] );
}
//各種カウンタの初期化
//gi_updateCountMs = 0;
gi_updateCountMs = Math.trunc(Math.random() * giA_updateIntervalMs[gi_dispMode] / 1000) * 1000;
gi_displayPaused = 0;
gelm0 = gelm1 = gelm2 = gelm3 = gelm4 = gelm5 = gelm6 = gelm7 = gelm8 = gelm9 = null;
//console.log("☆clearElements [" + gi_updateCountMs + "]" );
//監視対象の要素オブジェクト
if( gi_dispMode == MODE_HOME ){
gelm1 = document.querySelectorAll('div[aria-label="タイムライン: ホームタイムライン"]');
}else if( gi_dispMode == MODE_LIST ){
gelm1 = document.querySelectorAll('div[aria-label="タイムライン: リスト"]');
}else if( gi_dispMode == MODE_USER ){
gelm1 = document.querySelectorAll('div[aria-label^="タイムライン: "][aria-label$="さんのポスト"]');
}else if( gi_dispMode == MODE_NOTI ){
gelm1 = document.querySelectorAll('div[aria-label="タイムライン: 通知"]');
}else if( gi_dispMode == MODE_SEAR ){
gelm1 = document.querySelectorAll('div[aria-label="タイムライン: タイムラインを検索"]');
}
if( gelm1.length > 0 ) gelm0 = gelm1[0].firstElementChild;
if( gelm0 === null ){
//ドキュメント未構成のため時間を置いてリトライ
window.setTimeout(clearElements, gi_initWaitMs);
//console.log("☆clearElements Retry Timer" );
return;
}
var i;
//固定ツイートを非表示にするための目印追加
if( gi_dispMode == MODE_USER ){
gelm2 = gelm0.firstElementChild;
if( gelm2 !== null ){
gelm3 = gelm2.querySelectorAll('span');
for( i=0; i < gelm3.length; i++ ){
if( gelm3[i].textContent == "固定" ){
gelm2.setAttribute(gstr_scrFixedUserAttr,"true");
gelm4 = gelm2.firstElementChild;
break;
}
}
}
}
//検索ページで「話題のツイート」を非表示にしていた場合に「最新」にフォーカスを移す (style.displayでは状態が獲得出来ないのでclientHeigtを見るべし)
if( gi_dispMode == MODE_SEAR ){
gelm3 = document.querySelectorAll('div[aria-label="ホームタイムライン"] div[role="tablist"][data-testid="ScrollSnap-List"] div[role="presentation"]:has(a[role="tab"])');
if( gelm3.length > 1 ){
gelm4 = gelm3[0].querySelectorAll('a[role="tab"]');
gelm5 = gelm3[1].querySelectorAll('a[role="tab"]');
if( gelm4.length > 0 && gelm5.length > 0 ){
if( gelm4[0].clientHeight == 0 && gelm4[0].getAttribute("aria-selected") == "true" ){
gelm5[0].click();
}
}
}
}
//既に張られているovserverを消去
observer.disconnect();
//要素の変化監視をスタート
observer.observe(gelm0, configObserver);
//表示更新用エレメントの再取得
gelm_dispInfo = null;
gi_initComplete = 1;
//if(filePfx!==null) logSave(gstrA_modeNamePrifix[gi_dispMode] + " CLEAR ");
//console.log("★clear: Element");
}
//URLからモードを決定する
function getModeFromURL(){
//画面遷移が発生したので動作モードの決定
var hr = window.location.href;
if( hr == (TWITTER_URL + PATH_HOME)){
gi_dispMode = MODE_HOME;
}else if( hr.indexOf(TWITTER_URL + PATH_LIST) != -1 ){
gi_dispMode = MODE_LIST;
}else if( hr.indexOf(TWITTER_URL + PATH_NOTI) != -1 ){
gi_dispMode = MODE_NOTI;
}else if( hr.indexOf(TWITTER_URL + PATH_SEAR) != -1 ){
gi_dispMode = MODE_SEAR;
}else if(isOtherURL(hr)){
gi_dispMode = MODE_NULL;
}else if( hr.indexOf(TWITTER_URL) != -1 ){
//ユーザーアカウント名で終わるURLなので消去法で各種ページを除外していかないと判定が出来ない
gi_dispMode = MODE_USER;
}else{
gi_dispMode = MODE_NULL;
}
}
//RTされた同一の記事が複数表示されないようにする
function removeSameArticle(){
var e0, e1, e2, e3, at;
//重複の削除
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(a[href*="/status/"]):has(span[datetime])');
for(var i=e0.length-1; i > -1; i--){
e1 = e0[i].querySelectorAll('a[href*="/status/"]:has(span[datetime])');
if( e1[0] !== null ){
for(var j=0; j < i; j++){
e2 = e0[j].querySelectorAll('a[href*="/status/"]:has(span[datetime])');
if( e2[0] !== null ){
var u1 = e1[0].getAttribute('href');
var u2 = e2[0].getAttribute('href');
//console.log("★ removeSameArticle i=" + i + " : " + u1 + " # j=" + j + " : " + u2 );
if( u1 == u2 ){
//console.log("★removeSameArticle: HIT i=" + i + " / j=" + j + " : " + u2 );
e0[j].style.display = "none";
e0[j].setAttribute(gstr_multipleArticleAttr, "1");
}
}
}
}
}
}
const HOME_NEW_TWEET = '[class="css-18t94o4 css-1dbjc4n r-1777fci r-dfe81l r-1ny4l3l r-o7ynqc r-6416eg r-13qz1uu"]';
//短周期処理(タイムスタンプ置換、表示タイトル変更、さらに表示系の自動押下)
function replaceEtements() {
var e0, e1, e2, e3, e4, e5, e6, idx;
var dt = new Date();
//新着表示をクリックした場合にも更新時間を記録
e0 = document.querySelectorAll('body');
if( e0.length > 0 ){
e1 = e0[0].querySelectorAll('div[aria-label="タイムライン: ホームタイムライン"] div[data-testid="cellInnerDiv"]:has(' + HOME_NEW_TWEET + ')');
if( e1.length > 0 ){
if( e0[0].getAttribute(gstr_scrNewTweetAttr) == null){
if( gi_hideNumberNewTweet ){
e0[0].setAttribute(gstr_scrNewTweetAttr, 'false');
e1[0].display = "none";
}else{
e0[0].setAttribute(gstr_scrNewTweetAttr, 'true');
e1[0].display = null;
}
}
e2 = e1[0].querySelectorAll( HOME_NEW_TWEET + ':not([' + gstr_scrNewTweetAttr + '])');
for( idx=0; idx < e2.length; idx++ ){
//イベントリスナーを多重登録しないよう目印をつける
e2[idx].setAttribute(gstr_scrNewTweetAttr, 'true');
console.log("★replaceElements0 新着のエレメント発見[" + idx + "]");
e2[idx].addEventListener('click', onClickNewTweet);
}
}
}
//重複記事の非表示
if( gi_notDispSameArticle ){
removeSameArticle();
}
//タイムスタンプ置換・既読マークを全アーティクルに対して実施する
document.querySelectorAll('main div[data-testid="primaryColumn"] section article a[href*="/status/"] time:not([' + TIME_FIXED + '])').forEach(function(e) {
var a = e.parentNode;
var b = a.parentNode;
var h = a.getAttribute('href');
var s0 = e.getAttribute('datetime');
var s1 = toFormatedDateString(new Date(s0));
var span;
if( gi_replaceTimeStamp ){
//置換をする設定の場合
span = document.createElement('span');
span.setAttribute('datetime', s0);
span.setAttribute('local-datetime', s1);
span.textContent = s1;
a.appendChild(span);
a.removeChild(e);
}else{
//置換をしない設定の場合は目印をつけておかないと毎回チェックボックスが増えてしまう
e.setAttribute(TIME_FIXED,"");
}
var u = window.location.href;
u = u.replace( TWITTER_URL, "");
//遷移直後にURLがhomeなのにgi_dispModeが0のような事があるので再判定
if( gi_dispMode == MODE_NULL ){
getModeFromURL();
}
//既読マークの処理
if( gi_enableReadPointCheckBox ){
if( gi_dispMode == MODE_HOME || gi_dispMode == MODE_LIST || gi_dispMode == MODE_USER || gi_dispMode == MODE_SEAR ){
//チェックボックスの下地になるdiv作成
var dv = document.createElement("div");
dv.setAttribute(gstr_scrReadPointParentAttr,"");
dv.style.display = "flex";
dv.style.marginTop = '0px';
dv.style.marginBottom = '0px';
dv.style.marginLeft = '3px';
dv.style.marginRight = '0px';
dv.style.backgroundColor = COLOR_BORDER;
dv.style.borderWidth = "0px";
//既読ポイントのチェックボックス追加
var chk = document.createElement('input');
chk.setAttribute('type','checkbox');
chk.setAttribute(gstr_scrReadPointAttr,'false');
for( idx=0; idx < gi_readArticles; idx++ ){
if( window.localStorage.getItem( READ_HEADER[idx] + u ) == h ){
chk.setAttribute(gstr_scrReadPointAttr,'true' + idx);
chk.checked = true;
}
}
chk.setAttribute('href', h);
chk.setAttribute(CHK_TIMESTAMP, s1);
chk.style.marginTop = '2px';
chk.style.marginBottom = '2px';
chk.style.marginLeft = '2px';
chk.style.marginRight = '2px';
if( gi_readCheckedColorMode > -1 ){
chk.style.opacity = CHECKBOX_ENABLE_OPACITY;
}else{
chk.style.opacity = CHECKBOX_DISABLE_OPACITY;
}
//stopPropagationのあと無名関数自身をreturn falseで返さないと親エレメントのイベントが止まらない
chk.onchange = function(e){e.stopPropagation(); chgReadPoint(e.target,0); appendNextReadCheck(); return false;};
chk.oncontextmenu = function(e){e.stopPropagation(); rclickReadPoint(true, false); return false;};
dv.appendChild(chk);
b.appendChild(dv);
//先祖要素を探して色替え
for( idx = 0; idx < gi_readArticles; idx++ ){
e1 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '="true' + idx + '"][href="' + h + '"])');
if( e1.length> 0 ){
if( gi_readCheckedColorMode > -1 ){
e1[0].style.backgroundColor = READ_COLOR_ENABLED[idx];
}else{
e1[0].style.backgroundColor = null;
}
gstrA_readTimeStamp[idx] = s1;
gstrA_readArticleURL[idx] = h;
}
}
}else{
//console.log("★ gi_dispMode=" + gi_dispMode + " / " + u );
}
}
});
//画像リンクの処理
if( gi_displayImageNewTab ){
document.querySelectorAll('a[href*="/status/"][role="link"]:not([' + IMAGE_LINK + ']):is([href$="/photo/1"],[href$="/photo/2"],[href$="/photo/3"],[href$="/photo/4"]):has(img[draggable="true"])').forEach(function(e) {
e.setAttribute( IMAGE_LINK, "" );
//console.log("★Image find=" + e.getAttribute('href'));
e.onclick = function(e){
e.stopPropagation();
var h = e.target.getAttribute('src');
if( h.indexOf('?') > -1 ){
h = h.substr(0, h.indexOf('?')) + "?format=jpg&name=orig";
}
//console.log("★Image href=" + h + " / obj=" + e.target.parentNode.parentNode.parentNode);
window.open( h, '_blank' );
return false;
};
});
}
//console.log("★ 1 Title=" + document.title);
if( document.title.indexOf('@') != -1 ){
var t, idx1, idx2;
// Listページ タブタイトルの変更 「@USERNAME/ListName」→「ListName」
if( window.location.href.indexOf(TWITTER_URL + PATH_LIST) !== -1 ){
t = document.title;
idx1 = t.indexOf('@');
idx2 = t.indexOf('/');
if( idx1 !== -1 && idx2 !== -1 ) document.title = t.substr(idx2+1);
}else{
// Userページ タブタイトルの変更 「Posts with replies by 」など削除
document.title = document.title.replace('Posts with replies by ','');
document.title = document.title.replace('Media posts by ','');
document.title = document.title.replace('Posts liked by ','');
// 通知があると先頭に(1)とかが付くのでこのあとのタブタイトル置換でidx2の値がidx1より手前になってしまうのを回避
// 「(1) DISPNAME (@USERNAME) / X」→「DISPNAME (@USERNAME) / X」
// 「(1) DISPNAME(@USERNAME)さん / X」→「DISPNAME(@USERNAME)さん / X」
t = document.title;
idx1 = t.indexOf(")");
idx2 = t.indexOf("@");
if( t.substr(0,1) == "(" && idx1 > 1 && (idx2 - 5) > idx1 ){
document.title = t.substr(idx1+1);
//console.log("★ 3 Title=" + document.title);
}
// Userページ タブタイトルの変更 「DISPNAME (@USERNAME)」→「[@USERNAME]」
t = document.title;
idx1 = t.indexOf(' (@');
idx2 = t.indexOf(')');
if( idx1 !== -1 && idx2 !== -1 ) document.title = '[' + t.substr(idx1+3, idx2-idx1-3) + ']';
// Userページ タブタイトルの変更 「DISPNAME(@USERNAME)さん / X」→「[@USERNAME]」
t = document.title;
idx1 = t.indexOf('(@');
idx2 = t.indexOf(')さん');
if( idx1 !== -1 && idx2 !== -1 ) document.title = '[' + t.substr(idx1+2, idx2-idx1-2) + ']';
}
}
// 個別ツイート表示先頭の「Xユーザーの」を削除
if(document.title.indexOf("Xユーザーの") == 0 ){
document.title = document.title.replace('Xユーザーの','');
}
// タブタイトル末尾の 「/ X」を削除
document.title = document.title.replace('\/ X','');
//console.log("★ 2 Title=" + document.title);
//遡りスクロール中に出てきた「さらに」表示はモードに関係なくトリガさせる
if( ( gi_displayPaused == 1 && window.pageYOffset > window.innerHeight ) ||
( ( gi_autoClickNewTweet && (gi_modeAutoOff == 0 || gi_displayPaused == 0) ) &&
( window.pageYOffset <= SCROLL_LIMIT || window.pageYOffset > window.innerHeight / 2 ) ) ){
e2 = document.querySelectorAll(HOME_NEW_TWEET);
}
if( e2 != null ){
for( idx=0; idx < e2.length; idx++ ){
if( gi_displayPaused == 1 && window.pageYOffset > window.innerHeight ) {
e3 = e2[idx].firstElementChild;
if( e3 !== null ){
e4 = e3.firstElementChild;
if( e4 !== null ){
e5 = e4.firstElementChild;
if( e5 !== null ){
e6 = e5.textContent;
if( e6.indexOf("さらに") != -1 || e6.indexOf("More") != -1 || e6.indexOf("more") != -1 ){
//色替え・半自動更新表示
forceUpdateColor(COLOR_UPDATE, TXT_AUTOCLICKMOR);
console.log("★replaceElements1 「さらに」のエレメント発見、トリガ[" + idx + "]");
e2[idx].click();
return;
}
}
}
}
}
//自動更新OFFのボタンが押されて有効となっている場合は自動クリックも停止
if( gi_autoClickNewTweet && (gi_modeAutoOff == 0 || gi_displayPaused == 0) &&
( window.pageYOffset <= SCROLL_LIMIT || window.pageYOffset > window.innerHeight / 2 ) ) {
forceUpdateColor(COLOR_UPDATE, TXT_AUTOCLICKMOR);
console.log("★replaceElements2 新着のエレメントを自動クリック[" + idx + "]");
e2[idx].click();
return;
}
//手動更新直後に新着表示だけされて読み込まれないパターンの救済
if( gi_manualUpdateTriggerNewTweet && (dt.getTime() - gdt_lastTriggerTime.getTime() < gi_manualUpdateIntervalSec * 1000) ){
forceUpdateColor(COLOR_UPDATE, TXT_AUTOCLICKMOR);
console.log("★replaceElements3 新着のエレメントを自動クリック[" + idx + "]");
e2[idx].click();
return;
}
}
}
}
//新着表示部のクリックイベントで更新表示と時間記録を行う
function onClickNewTweet(){
if( gi_modeAutoOff ){
//色替え・手動更新表示
forceUpdateColor(COLOR_UPDATE, TXT_MANUALUPDATE);
}else{
//色替え・自動クリック更新表示
forceUpdateColor(COLOR_UPDATE, TXT_AUTOCLICKMOR);
}
//更新トリガの時間を記録
gdt_lastTriggerTime = new Date();
//手動でトリガを掛けたので更新カウンタ時間を満了時間にする
gi_updateCountMs = giA_updateIntervalMs[gi_dispMode] - 1000;
}
//既読ポイントの変更
function chgReadPoint(obj, idx){
if( ! gi_enableReadPointCheckBox ) return;
if( gi_dispMode != MODE_HOME && gi_dispMode != MODE_LIST && gi_dispMode != MODE_USER && gi_dispMode != MODE_SEAR ) return;
var i, j, e0, e1, flg = false;
var h = window.location.href;
h = h.replace( TWITTER_URL, "");
if( obj !== null ){
var c = false;
var u = "";
c = obj.checked;
u = obj.getAttribute('href');
//既にチェック済みになっているエレメントを戻す
if( idx == 0 ){
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '^="true"])');
for( i = 0; i < e0.length; i++ ){
e0[i].style.backgroundColor = null;
e1 = e0[i].querySelectorAll('input[' + gstr_scrReadPointAttr + ']');
if( e1.length > 0 ){
e1[0].checked = false;
e1[0].setAttribute(gstr_scrReadPointAttr,'false');
}
}
}
//操作されたエレメントの更新
if( c == true ){
//チェックが付けられたアーティクルの色替えとローカル保存
obj.setAttribute(gstr_scrReadPointAttr,'true' + idx );
obj.checked = true;
e1 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '="true' + idx + '"][href="' + u + '"])');
if( e1.length> 0 ){
if( gi_readCheckedColorMode > -1 ){
e1[0].style.backgroundColor = READ_COLOR_ENABLED[idx];
}else{
e1[0].style.backgroundColor = null;
}
window.localStorage.setItem( READ_HEADER[idx] + h, u );
gstrA_readTimeStamp[idx] = obj.getAttribute(CHK_TIMESTAMP);
gstrA_readArticleURL[idx] = obj.getAttribute('href');
}
}else{
//チェックが外されたアーティクルを戻しローカル保存データの破棄
obj.checked = false;
obj.setAttribute(gstr_scrReadPointAttr,'false');
//チェック数の定義を減らした後にゴミが残らないように最大数まで探して消す
for( i=0; i< 100; i++ ){
//定義数が減った時に定義が残るのでクリアする手段
window.localStorage.removeItem( READ_HEADER[i] + h );
if( i < gi_readArticles ){
gstrA_readTimeStamp[i] = "";
gstrA_readArticleURL[i] = "";
}
}
}
}
}
//既読ポイントの有効無効切り替え
function chgReadPointMode(){
if( ! gi_enableReadPointCheckBox ) return;
if( gi_dispMode != MODE_HOME && gi_dispMode != MODE_LIST && gi_dispMode != MODE_USER && gi_dispMode != MODE_SEAR ) return;
var i, e0, e1, idx;
var h = window.location.href;
h = h.replace( TWITTER_URL, "");
//色と透明度を戻す
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '^="true"])');
for( i = 0; i < e0.length; i++ ){
e1 = e0[i].querySelectorAll('input[' + gstr_scrReadPointAttr + ']');
if( e1.length > 0 ){
idx = Number((e1[0].getAttribute(gstr_scrReadPointAttr)).replace("true",""));
if( gi_readCheckedColorMode > -1 ){
e0[i].style.backgroundColor = READ_COLOR_ENABLED[idx];
e1[0].style.opacity = CHECKBOX_ENABLE_OPACITY;
}else{
e0[i].style.backgroundColor = null;
e1[0].style.opacity = CHECKBOX_DISABLE_OPACITY;
}
}
}
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '="false"])');
for( i = 0; i < e0.length; i++ ){
e1 = e0[i].querySelectorAll('input[' + gstr_scrReadPointAttr + ']');
if( e1.length > 0 ){
e0[i].style.backgroundColor = null;
if( gi_readCheckedColorMode > -1 ){
e1[0].style.opacity = CHECKBOX_ENABLE_OPACITY;
}else{
e1[0].style.opacity = CHECKBOX_DISABLE_OPACITY;
}
}
}
}
//手動更新時に既読ポイントを現在表示中の最新アーティクルから自動設定する
function updateReadCheck(){
var e0, e1, e2, e3, e4, e5;
var idx = 0;
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '])');
for( var i=0; i< e0.length; i++ ){
if( e0[i].style.display != "none" && e0[i].clientHeight > 0 && e0[i].getAttribute(gstr_multipleArticleAttr) != "1" && e0[i].getAttribute(gstr_scrFixedUserAttr) != "1" ){
e1 = e0[i].querySelectorAll('input[' + gstr_scrReadPointAttr + ']');
if( e1.length > 0 ){
e2 = e0[i].firstElementChild;
if( e2 !== null ){
//1階層下・2階層下のエレメントでdisplay=noneになっている場合がある
if( e2.style.display != "none" && e2.clientHeight > 0 ){
e3 = e2.firstElementChild;
if( e3 !== null ){
if( e3.style.display != "none" && e3.clientHeight > 0 ){
e1[0].checked = true;
//チェック更新処理
chgReadPoint(e1[0] ,idx++);
if( idx == gi_readArticles ) return;
}
}
}
}
}
}
}
}
//既読ポイント設定時に続く数件を自動設定する
function appendNextReadCheck(){
var e0, e1, e2, e3, e4, e5;
var idx = 0;
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '])');
for( var i=0; i< e0.length; i++ ){
if( e0[i].style.display != "none" && e0[i].clientHeight > 0 && e0[i].getAttribute(gstr_multipleArticleAttr) != "1" && e0[i].getAttribute(gstr_scrFixedUserAttr) != "1" ){
e1 = e0[i].querySelectorAll('input[' + gstr_scrReadPointAttr + ']');
if( e1.length > 0 ){
e2 = e0[i].firstElementChild;
if( e2 !== null ){
//1階層下・2階層下のエレメントでdisplay=noneになっている場合がある
if( e2.style.display != "none" && e2.clientHeight > 0 ){
e3 = e2.firstElementChild;
if( e3 !== null ){
if( e3.style.display != "none" && e3.clientHeight > 0 ){
//チェックされた本体の特定
if( idx == 0 && e1[0].checked == true ){
idx++;
}else if( idx > 0 ){
//チェック更新処理
e1[0].checked = true;
chgReadPoint(e1[0] ,idx++);
}
if( idx == gi_readArticles ) return;
}
}
}
}
}
}
}
}
//既読マーク背景色切り替え
function changeReadPointColor(){
if( ! gi_enableReadPointCheckBox ) return;
switch( gi_readCheckedColorMode ){
case 0:
READ_COLOR_ENABLED = READ_COLOR_ENABLED1;
break;
case 1:
READ_COLOR_ENABLED = READ_COLOR_ENABLED2;
break;
case 2:
READ_COLOR_ENABLED = READ_COLOR_ENABLED3;
break;
case 3:
READ_COLOR_ENABLED = READ_COLOR_ENABLED4;
break;
}
chgReadPointMode();
}
//既読マーク背景色設定の読込
function loadReadPointColorSetting(){
if( ! gi_enableReadPointCheckBox ) return;
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
gi_readCheckedColorMode = Number(window.localStorage.getItem(CHKCOLOR_HEADER + u));
changeReadPointColor();
}
//既読ポイントチェックボックスの右クリック
function rclickReadPoint(doCycle, notDispMsg){
if( ! gi_enableReadPointCheckBox ) return;
var i, j, e0;
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
if( doCycle ){
//表示色の入れ替え
if( ++gi_readCheckedColorMode >= READ_COLOR_CYCLE ) gi_readCheckedColorMode = -1;
window.localStorage.setItem(CHKCOLOR_HEADER + u, gi_readCheckedColorMode);
}
changeReadPointColor();
if( gi_readCheckedColorMode > -1 ){
forceUpdateColor(COLOR_WHITE, TXT_CHANGEBGTYPE.replace("#", Number(gi_readCheckedColorMode + 1)));
for( i = 0; i < gi_readArticles; i++ ){
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '="true' + i + '"])');
for( j = 0; j < e0.length; j++ ){
e0[j].style.backgroundColor = READ_COLOR_ENABLED[i];
}
}
if( ! notDispMsg ){
dispPopupMessage("既読マークの背景色をType" + (gi_readCheckedColorMode+1) + "に変更しました", gi_displayPopupCloseTimeSec);
}
}else{
forceUpdateColor(COLOR_WHITE, TXT_CHANGEBGNONE);
for( i = 0; i < gi_readArticles; i++ ){
e0 = document.querySelectorAll('div[data-testid="cellInnerDiv"]:has(input[' + gstr_scrReadPointAttr + '="true' + i + '"])');
for( j = 0; j < e0.length; j++ ){
e0[j].style.backgroundColor = null;
}
}
if( ! notDispMsg ){
dispPopupMessage("既読マークを非表示に変更しました", gi_displayPopupCloseTimeSec);
}
}
}
//URLごとの各種設定をローカルストレージから読み込む
function findSettings(){
var v;
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
//インターバル値を一旦初期状態に戻す
giA_updateIntervalMs = giA_defaultIntervalMs;
v = window.localStorage.getItem( INTERVAL_HEADER + u );
if( v !== null ){
v = Number(v);
if( v >= 10 && v <= 3600 ){
giA_updateIntervalMs[gi_dispMode] = v * 1000;
gi_updateCountMs = 0;
//console.log("☆findSettings [" + gi_updateCountMs + "]" );
}
}
//強制リロードまでの時間を一旦初期状態に戻す
gi_reloadTimeoutSec = gi_defaultReloadTimeoutSec;
v = window.localStorage.getItem( RELOAD_HEADER + u );
if( v !== null ){
v = Number(v);
if( v >= 0 && v <= 7200 ){
gi_reloadTimeoutSec = v;
}
}
//自動更新OFFの設定保存値を読み込む
gi_modeAutoOff = gi_defaultModeAutoOff;
v = window.localStorage.getItem( AUTOOFF_HEADER + u );
if( v !== null ){
v = Number(v);
if( v == 0 ){
//AUTO = ONにする
gi_modeAutoOff = 0;
}else{
//AUTO = OFFにする
gi_modeAutoOff = 1;
gi_displayPaused = 1;
}
}
//短周期タイマの常時ON設定保存値を読み込む
gi_idleShortTimer = gi_defalutIdleShortTimer;
v = window.localStorage.getItem( IDLETM_HEADER + u );
if( v !== null ){
v = Number(v);
if( v == 0 ){
//ずっと動作させ続けて停止させない
gi_idleShortTimer = 0;
}else{
//時間がたつと停止
gi_idleShortTimer = 1;
}
}
//手動更新禁止時間の設定保存値を読み込む
gi_manualUpdateIntervalSec = gi_defaultManualUpdateIntervalSec;
v = window.localStorage.getItem( MANUAL_HEADER + u );
if( v !== null ){
v = Number(v);
if( v >= 5 && v <= 60 ){
gi_manualUpdateIntervalSec = v;
}
}
//メディアサイズ設定を読み込む
gi_mediaSize = gi_defaultMediaSize;
v = window.localStorage.getItem( MEDIA_HEADER + u );
if( v !== null ){
v = Number(v);
gi_mediaSize = v;
}
//RT&引用RT設定を読み込む
gi_notDispRt = gi_defaultNotDispRt;
v = window.localStorage.getItem( NOTRT_HEADER + u );
if( v !== null ){
v = Number(v);
gi_notDispRt = v;
}
//メディアサイズ設定とRT非表示設定をドキュメント反映とローカル保存
updateMediaAttribute();
if( gi_dispMode == MODE_HOME ){
//ツイート欄表示非表示の設定保存値を読み込む
gi_hideEditControl = gi_defaultHideEditControl;
v = window.localStorage.getItem( EDITDISP_HEADER );
if( v !== null ){
v = Number(v);
if( v == 0 ){
//ツイート入力欄を非表示にしない
gi_hideEditControl = 0;
}else{
//ツイート入力欄を非表示にする
gi_hideEditControl = 1;
}
//console.log("★getItem" + EDITDISP_HEADER + " = " + gi_hideEditControl);
}
//上部の新着件数表示切り替えの設定値を読み込む
gi_hideNumberNewTweet = gi_defaultHideNumberNewTweet;
v = window.localStorage.getItem( NEWTWDISP_HEADER );
if( v !== null ){
v = Number(v);
if( v == 0 ){
//新着表示を非表示にしない
gi_hideNumberNewTweet = 0;
}else{
//新着表示を非表示にする
gi_hideNumberNewTweet = 1;
}
//console.log("★getItem" + NEWTWDISP_HEADER + " = " + gi_hideNumberNewTweet);
}
swichDispNumberNewTweet(1);
}
}
//メディアサイズをドキュメントに設定し、ローカルにも保存
function updateMediaAttribute(){
var v, rt, quote;
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
//CSSで切り替わるようにメディアサイズ情報を書き込む
gelm0 = document.querySelectorAll('body');
if( gelm0.length > 0 ){
gelm0[0].setAttribute( gstr_scrMediaAttr, gi_mediaSize );
}
window.localStorage.setItem( MEDIA_HEADER + u, gi_mediaSize );
//RT非表示設定をドキュメントに設定し、ローカルにも保存
switch(gi_notDispRt){
case 1: rt = 1; quote = 0; break;
case 2: rt = 0; quote = 1; break;
case 3: rt = 1; quote = 1; break;
default: rt = 0; quote = 0; break;
}
//CSSで切り替わるようにメディアサイズ情報を書き込む
gelm0 = document.querySelectorAll('body');
if( gelm0.length > 0 ){
gelm0[0].setAttribute( gstr_scrNotRtAttr, rt );
gelm0[0].setAttribute( gstr_scrNotQuoteAttr, quote );
}
window.localStorage.setItem( NOTRT_HEADER + u, gi_notDispRt );
}
//クリックで入力ダイアログを入力させるボタン部と自動更新のON/OFFをするボタン部を生成
function setupElement(parentElm){
//既にあったら消す
if( gelm_btnEdit !== null ) gelm_btnEdit.remove();
if( gelm_btnAutoOff !== null ) gelm_btnAutoOff.remove();
if( gelm_btnInterval !== null ) gelm_btnInterval.remove();
if( gelm_btnShort !== null ) gelm_btnShort.remove();
if( gelm_btnHelp !== null ) gelm_btnHelp.remove();
if( gelm_dispInfo !== null ) gelm_dispInfo.remove();
if( gelm_btnParent !== null ) gelm_btnParent.remove();
if( gelm_allParent !== null ) gelm_allParent.remove();
//基準となる元エレメントのプロパティ
parentElm.style.display = "flex";
parentElm.style.fontSize = gstrA_titleSize[gi_dispMode];
//親エレメント生成
gelm_allParent = document.createElement("div");
gelm_allParent.setAttribute("id",PARENT_BLOCK);
gelm_allParent.style.display = "flex";
gelm_allParent.style.marginLeft = "3px";
gelm_allParent.style.marginRight = "3px";
gelm_allParent.style.backgroundColor = COLOR_BLACK;
gelm_allParent.style.border = COLOR_BORDER;
gelm_allParent.style.borderStyle = "solid";
gelm_allParent.style.borderWidth = "1px";
gelm_allParent.style.opacity = gf_dispUnitOpacity;
//stopPropagationのあと無名関数自身をreturn falseで返さないと親エレメントのイベントが止まらない
gelm_allParent.onclick = function(e){e.stopPropagation();return false;};
gelm_allParent.oncontextmenu = function(e){e.stopPropagation();return false;};
parentElm.appendChild(gelm_allParent);
//自動更新情報表示のエレメント生成
gelm_dispInfo = document.createElement("div");
gelm_dispInfo.setAttribute("id",INFO_BLOCK);
gelm_dispInfo.style.display = "block";
gelm_dispInfo.style.textAlignLast = "center";
gelm_dispInfo.style.width = DISPINFO_WIDTH;
gelm_dispInfo.style.height = DISPINFO_HEIGHT;
gelm_dispInfo.style.overflowX = "hidden";
gelm_dispInfo.style.overflowY = "hidden";
gelm_dispInfo.style.color = COLOR_GRAY;
gelm_dispInfo.style.backgroundColor = COLOR_BLACK;
gelm_dispInfo.style.fontSize = gstrA_titleSize[gi_dispMode];
gelm_dispInfo.style.border = COLOR_BORDER;
gelm_dispInfo.style.borderStyle = "solid";
gelm_dispInfo.style.borderWidth = "1px";
gelm_dispInfo.textContent = "";
gelm_dispInfo.onclick = clickInformationButton1;
gelm_dispInfo.oncontextmenu = clickInformationButton2;
gelm_allParent.appendChild(gelm_dispInfo);
//ボタン親エレメント生成
gelm_btnParent = document.createElement("div");
gelm_btnParent.setAttribute("id",BUTTON_BLOCK);
gelm_btnParent.style.display = "flex";
gelm_btnParent.style.marginLeft = "0px";
gelm_btnParent.style.marginRight = "0px";
gelm_btnParent.style.backgroundColor = COLOR_BORDER;
gelm_btnParent.style.borderWidth = "0px";
//stopPropagationのあと無名関数自身をreturn falseで返さないと親エレメントのイベントが止まらない
gelm_btnParent.onclick = function(e){e.stopPropagation();return false;};
gelm_btnParent.oncontextmenu = function(e){e.stopPropagation();return false;};
gelm_allParent.appendChild(gelm_btnParent);
//ヘルプダイアログボタンのエレメント生成
gelm_btnHelp = document.createElement("div");
gelm_btnHelp.setAttribute("id",HELP_BLOCK);
gelm_btnHelp.style.display = "flex";
gelm_btnHelp.style.color = COLOR_GRAY;
gelm_btnHelp.style.backgroundColor = COLOR_BLACK;
gelm_btnHelp.style.fontSize = gstrA_buttonSize[gi_dispMode];
gelm_btnHelp.style.border = COLOR_BORDER;
gelm_btnHelp.style.borderStyle = "solid";
gelm_btnHelp.style.borderWidth = "1px";
gelm_btnHelp.textContent = BTN_TXT_HLP;
gelm_btnHelp.onclick = dispInfoDialog;
gelm_btnHelp.oncontextmenu = dispReadDialog;
gelm_btnParent.appendChild(gelm_btnHelp);
//インターバル設定ボタンのエレメント生成
gelm_btnInterval = document.createElement("div");
gelm_btnInterval.setAttribute("id",INTERVAL_BLOCK);
gelm_btnInterval.style.display = "flex";
gelm_btnInterval.style.color = COLOR_GRAY;
gelm_btnInterval.style.backgroundColor = COLOR_BLACK;
gelm_btnInterval.style.fontSize = gstrA_buttonSize[gi_dispMode];
gelm_btnInterval.style.border = COLOR_BORDER;
gelm_btnInterval.style.borderStyle = "solid";
gelm_btnInterval.style.borderWidth = "1px";
gelm_btnInterval.textContent = BTN_TXT_INT;
gelm_btnInterval.onclick = dispSettingMessage;
gelm_btnInterval.oncontextmenu = dispSettingMessage;
gelm_btnParent.appendChild(gelm_btnInterval);
//短周期タイマ設定ボタンのエレメント生成
gelm_btnShort = document.createElement("div");
gelm_btnShort.setAttribute("id",SHORT_BLOCK);
gelm_btnShort.style.display = "flex";
gelm_btnShort.style.color = COLOR_IDL_DISABL;
gelm_btnShort.style.backgroundColor = COLOR_BLACK;
gelm_btnShort.style.fontSize = gstrA_buttonSize[gi_dispMode];
gelm_btnShort.style.border = COLOR_BORDER;
gelm_btnShort.style.borderStyle = "solid";
gelm_btnShort.style.borderWidth = "1px";
gelm_btnShort.textContent = BTN_TXT_SRT;
gelm_btnShort.onclick = idleTimerChange;
gelm_btnShort.oncontextmenu = dispSettingMessage;
gelm_btnParent.appendChild(gelm_btnShort);
//自動更新ON/OFF設定ボタンのエレメント生成
gelm_btnAutoOff = document.createElement("div");
gelm_btnAutoOff.setAttribute("id",AUTO_BLOCK);
gelm_btnAutoOff.style.display = "flex";
gelm_btnAutoOff.style.color = COLOR_AUT_DISABL;
gelm_btnAutoOff.style.backgroundColor = COLOR_BLACK;
gelm_btnAutoOff.style.fontSize = gstrA_buttonSize[gi_dispMode];
gelm_btnAutoOff.style.border = COLOR_BORDER;
gelm_btnAutoOff.style.borderStyle = "solid";
gelm_btnAutoOff.style.borderWidth = "1px";
gelm_btnAutoOff.textContent = BTN_TXT_AUT;
gelm_btnAutoOff.onclick = switchAutoButton;
gelm_btnAutoOff.oncontextmenu = dispSettingMessage;
gelm_btnParent.appendChild(gelm_btnAutoOff);
if( gi_dispMode == MODE_HOME ){
//ツイート欄ON/OFF設定ボタンのエレメント生成
gelm_btnEdit = document.createElement("div");
gelm_btnEdit.setAttribute("id",EDITBTN_BLOCK);
gelm_btnEdit.style.display = "flex";
gelm_btnEdit.style.color = COLOR_BLACK;
gelm_btnEdit.style.backgroundColor = COLOR_BLACK;
gelm_btnEdit.style.fontSize = gstrA_buttonSize[gi_dispMode];
gelm_btnEdit.style.border = COLOR_BORDER;
gelm_btnEdit.style.borderStyle = "solid";
gelm_btnEdit.style.borderWidth = "1px";
gelm_btnEdit.textContent = " ";
gelm_btnEdit.onclick = function(){gi_hideEditControl=(gi_hideEditControl==0)?1:0; swichEditColumn();};
gelm_btnEdit.oncontextmenu = function(){gi_hideNumberNewTweet=(gi_hideNumberNewTweet==0)?1:0; swichDispNumberNewTweet(0);};
gelm_btnParent.appendChild(gelm_btnEdit);
swichEditColumn();
}
}
//クリック操作による短周期タイマ再開と更新トリガ
function clickInformationButton(rclick){
var dt = new Date();
//スクロール中は最上部のアーティクルが読まれていない状態の事があるので先頭よりちょっと下に戻るのみ(先頭に戻すとトリガされてしまう)
if( window.pageYOffset > window.innerHeight ){
window.scrollTo(0, SCROLL_LIMIT + 1.0);
return;
}
//短周期タイマの再開
if( gi_idleShortTimer && (!rclick && gi_restartShortTimerL || rclick && gi_restartShortTimerR) ){
if( gtmr_shortTimer === null ){
gtmr_shortTimer = window.setInterval(replaceEtements, gi_shortIntervalMs);
gstr_lastShortStart = dt;
//console.log("★gtmr_shortTimer: START[startShortTimerByButton]");
}
}
//通知ページの新着表示を戻す
if( (!rclick && gi_clearNewNotificationL || rclick && gi_clearNewNotificationR ) && gi_dispMode == MODE_NOTI ){
clearNewNotification();
}
if( gi_dispMode != MODE_HOME && gi_dispMode != MODE_LIST && gi_dispMode != MODE_USER && gi_dispMode != MODE_SEAR ) return;
//自動で最新表示中のアーティクルを既読マークする
if( (!rclick && gi_manualUpdateAutoCheckL || rclick && gi_manualUpdateAutoCheckR ) && gi_enableReadPointCheckBox ){
updateReadCheck();
}
//更新禁止期間および設定で状態によって抑止されている時はトリガさせない
if( (!rclick && gi_manualUpdateTriggerDisableGreenL || rclick && gi_manualUpdateTriggerDisableGreenR ) &&
(gi_colorType == TYPE_UPDATE || gi_colorType == TYPE_UPSOON || gi_colorType == TYPE_ACTIVE || gi_colorType == TYPE_HOLDTM ) ) return;
if( (!rclick && gi_manualUpdateTriggerDisableBlueL || rclick && gi_manualUpdateTriggerDisableBlueR ) &&
(gi_colorType == TYPE_PAUSED || gi_colorType == TYPE_HOLDTM) ) return;
//前回の手動更新から時間が経過していたらトリガ
if( !rclick && gi_manualUpdateTriggerL || rclick && gi_manualUpdateTriggerR ){
if( dt.getTime() - gdt_lastTriggerTime.getTime() > gi_manualUpdateIntervalSec * 1000 ){
//色替え・手動更新表示
forceUpdateColor(COLOR_UPDATE, TXT_MANUALUPDATE);
//更新トリガの時間を記録
gdt_lastTriggerTime = dt;
//手動でトリガ
execTrigger();
//手動でトリガを掛けたのでインターバル時間はリセット
gi_updateCountMs = 0;
}
}
}
//情報表示部の左クリック
function clickInformationButton1(){
clickInformationButton(false);
}
//情報表示部の右クリック
function clickInformationButton2(){
clickInformationButton(true);
}
const NEW_NOTI_CONTROL_ELEMENT = 'div[aria-label="ホームタイムライン"] > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1)';
const NEW_NOTI_MARK_ELEMENT = 'nav[aria-label="メインメニュー"] a[aria-label^="通知("][aria-label$="件の未読通知)"]';
//通知ページの新着表示を戻す
function clearNewNotification(){
if( gtmr_waitClear !== null ) return;
var e0 = document.querySelectorAll(NEW_NOTI_CONTROL_ELEMENT);
if( e0.length > 0 ){
var e1 = document.querySelectorAll(NEW_NOTI_MARK_ELEMENT);
if( e1.length > 0 ){
var he = e0[0].clientHeight;
if( he < 50 ){
e0[0].style.height = "100px";
gb_flgClearNotification = true;
gtmr_waitClear = window.setTimeout( waitforNotificationClear, 1000 );
dispPopupMessage("新着通知の表示から戻します", gi_displayPopupCloseTimeSec);
}
}
}
}
//新着件数表示が無くなるまで待つ
function waitforNotificationClear(){
//多重で走らないようにタイマキャンセル
if( gtmr_waitClear !== null ){
window.clearTimeout(gtmr_waitClear);
gtmr_waitClear = null;
}
var e0 = document.querySelectorAll(NEW_NOTI_CONTROL_ELEMENT);
if( e0.length > 0 ){
var e1 = document.querySelectorAll(NEW_NOTI_MARK_ELEMENT);
if( e1.length > 0 ){
if( ++gi_chkNotificationCount < gi_chkNotificationCountMax ){
gtmr_waitClear = window.setTimeout( waitforNotificationClear, 1000 );
return;
}
}
//新着数を示すタグが消えても背景色の色替えが戻らない事があるのでスクロールを操作する
window.setTimeout( function(){ window.scrollTo(0, window.innerHeight);}, 5000 );
window.setTimeout( function(){ window.scrollTo(0, 0); gb_flgClearNotification = false;}, 5100 );
//console.log("★Finish!" + gi_chkNotificationCount);
gi_chkNotificationCount = 0;
e0[0].style.height = null;
}
}
/*
//ヘルプダイアログによる設定情報表示
function dispInfoDialog(){
var idx;
var aut = (gi_modeAutoOff) ? "ON" : "OFF";
var sht = (gi_idleShortTimer) ? "OFF" : "ON";
var rth = Math.floor(gi_reloadTimeoutSec / 3600);
var rtm = Math.floor(gi_reloadTimeoutSec % 3600 / 60);
var rts = gi_reloadTimeoutSec % 60;
var rtt = ("0" + rth).slice(-2) + ":" + ("0" + rtm).slice(-2) + ":" + ("0" + rts).slice(-2);
var reb = (gi_reloadTimeoutSec) ? rtt : "----";
var pat = decodeURIComponent(window.location.href.replace(TWITTER_URL, ""));
var siz = window.innerWidth + "x" + window.innerHeight;
var ntf = (gi_dispMode == MODE_NOTI) ? true : false;
var msg = SPT + "【X(Twitter)WEB 自動更新スクリプト】";
msg += SPC + "------------------------------------";
if(!ntf){
msg += SPC + "自動更新インターバル = " + giA_updateIntervalMs[gi_dispMode] / 1000 + "(sec)";
msg += SPC + "手動更新操作の禁止期間 = " + gi_manualUpdateIntervalSec + "(sec)";
msg += SPC + "自動更新の強制停止モード = " + aut;
}
msg += SPC + "短周期タイマ常時稼動モード = " + sht;
msg += SPC + "DOM更新受信最終時刻 = " + gstr_lastDomTime;
msg += SPC + "強制再起動までの待機時間 = " + reb;
msg += SPC + "メディアサムネイルの表示 = " + SIZE_NAME[gi_mediaSize];
msg += SPC + "RT&引用RTの表示設定";
msg += SPC + " = " + NOTRT_NAME[gi_notDispRt];
if( gi_dispMode == MODE_HOME ){
msg += SPC + "上部新着件数の表示設定 = " + ( (gi_hideNumberNewTweet) ? "OFF" : "ON" );
}
msg += SPC + "URL = /" + pat;
msg += SPC + "TabSize = " + siz;
msg += SPC + "------------------------------------";
msg += SPC + "情報表示欄";
if(!ntf){
msg += SPC + " : 左クリック=スクロール戻し";
}
if(gi_manualUpdateTriggerL){
msg += SPC + " +手動更新";
}
if(gi_manualUpdateAutoCheckL){
msg += SPC + " +自動既読マーク";
}
if(gi_restartShortTimerL){
msg += SPC + " +短周期タイマ再開";
}
if(gi_clearNewNotificationL && ntf){
msg += SPC + " +新着表示色クリア";
}
msg += SPC + " : 右クリック=スクロール戻し";
if(gi_manualUpdateTriggerR){
msg += SPC + " +手動更新";
}
if(gi_manualUpdateAutoCheckR){
msg += SPC + " +自動既読マーク";
}
if(gi_restartShortTimerR){
msg += SPC + " +短周期タイマ再開";
}
if(gi_clearNewNotificationR && ntf){
msg += SPC + " +新着表示色クリア";
}
msg += SPC + BTN_TXT_HLP + " : 左クリック=ヘルプダイアログの表示";
if(gi_enableReadPointCheckBox && !ntf){
msg += SPC + " : 左クリック=既読情報ダイアログの表示";
}
msg += SPC + BTN_TXT_INT + " : 左クリック=コンフィグ";
msg += SPC + " : 右クリック=コンフィグ";
msg += SPC + BTN_TXT_SRT + " : 左クリック=短周期タイマ切り替え";
msg += SPC + " : 右クリック=コンフィグ";
if(!ntf){
msg += SPC + BTN_TXT_AUT + " : 左クリック=自動更新OFF切り替え";
msg += SPC + " : 右クリック=コンフィグ";
}
if( gi_enableReadPointCheckBox ){
if( gi_readCheckedColorMode > -1 ){
msg += SPC + "チェックボックス : ColorType=[" + gi_readCheckedColorMode + "]";
}else{
msg += SPC + "チェックボックス : 非表示";
}
msg += SPC + " : 左クリック=" + gi_readArticles + "件を既読マーク";
msg += SPC + " : 右クリック=既読マーク背景色切替";
}
if( gi_dispMode == MODE_HOME ){
msg += SPC + BTN_TXT_ED0 + "/" + BTN_TXT_ED1;
msg += SPC + " : 左クリック=ツイート入力欄表示切り替え";
msg += SPC + " : 右クリック=上部の新着件数表示切り替え";
}
msg += SPC + "------------------------------------";
if(!ntf){
msg += SPC + "[COUNT / DOM時刻] , ";
}
msg += SPC + "[Latest / DOM時刻] :";
if(!ntf){
msg += SPC + " 緑:自動更新トリガ有効";
msg += SPC + " 黄:自動更新トリガ直前";
msg += SPC + " 赤:自動更新トリガ発行中";
if( ! gi_enableTimeAutoOff ){
msg += SPC + "[Paused Refresh] :";
}else{
msg += SPC + "[Paused / DOM時刻] :";
}
msg += SPC + " 青:自動更新停止中";
}else{
msg += SPC + " 緑:(通知ページは常時自動動作)";
}
msg += SPC + "表示内容に依存しない色替 :";
msg += SPC + " 水:手動更新の抑制期間中";
msg += SPC + " 紫:強制リロード直前";
msg += SPC + "------------------------------------";
msg += SPC + BTN_TXT_INT + "(明色) / " + BTN_TXT_HLP + "(暗色) :";
msg += SPC + " 基本色は情報表示部に準ずる";
msg += SPC + BTN_TXT_SRT + " :";
msg += SPC + " 短周期タイマ都度停止中";
msg += SPC + " 基本色は情報表示部に準ずる";
msg += SPC + " 灰:短周期タイマ停止中";
msg += SPC + " 短周期タイマ常時稼動中";
msg += SPC + " 基本色は情報表示部に準ずる";
if(!ntf){
msg += SPC + BTN_TXT_AUT + " :";
msg += SPC + " 自動更新の通常動作中";
msg += SPC + " 基本色は情報表示部に準ずる";
msg += SPC + " 自動更新の強制停止中";
msg += SPC + " 灰:自動更新強制停止中";
}
msg += SPC + "------------------------------------";
msg += SPC + "http://coltpythonkingcobra.g1.xrea.com/pseudoTweetdeck/";
window.alert(msg);
}
//情報表示ダイアログ(既読ポイント情報)
function dispReadDialog(){
if( ! gi_enableReadPointCheckBox || gi_readArticles < 0 || gi_dispMode == MODE_NOTI ) return;
var idx, dsp=0;
var msg = SPT + "【X(Twitter)WEB 自動更新スクリプト】";
msg += SPC + "------------------------------------";
msg += SPC + "既読ポイント数 : " + gi_readArticles;
if( gi_readCheckedColorMode > -1 ){
msg += SPC + "表示タイプ : " + Number(gi_readCheckedColorMode + 1) + " / " + READ_COLOR_CYCLE;
}else{
msg += SPC + "表示タイプ : 非表示中";
}
msg += SPC + "------------------------------------";
for( idx = 0; idx < gi_readArticles; idx++ ){
if( gstrA_readArticleURL[idx] != "" ){
msg += SPC + "既読ポイント" + Number(idx + 1) + ":(" + gstrA_readTimeStamp[idx] + ")";
msg += SPC + gstrA_readArticleURL[idx];
msg += SPC + "------------------------------------";
dsp++;
}}
if( dsp == 0 ){
msg += SPC + "現在既読ポイントは設定されていません";
msg += SPC + "------------------------------------";
}
msg += SPC + "http://coltpythonkingcobra.g1.xrea.com/pseudoTweetdeck/";
window.alert(msg);
}
//インターバル値を入力させる(通知ページの場合は新着表示のクリアインターバル)
function dispIntervalSetting(){
var txt;
if( gi_dispMode != MODE_NOTI ){
txt = "自動更新インターバル";
}else{
txt = "自動新着表示クリア間隔";
}
//URLを確認
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
var ret = window.prompt( SPT + txt + SPC + SPC + "URL = /" + u + SPC
+ "設定値: " + gi_manualUpdateIntervalSec + "〜3600(sec)", giA_updateIntervalMs[gi_dispMode] /1000);
if( ret === null ) return;
ret = Number(ret);
if( ret < gi_manualUpdateIntervalSec || ret > 3600 ) return;
//console.log("★InputValue = " + ret);
giA_updateIntervalMs[gi_dispMode] = ret * 1000;
gi_updateCountMs = 0;
localStorage.setItem( INTERVAL_HEADER + u, ret );
dispPopupMessage( txt + "を" + ret + "秒に変更しました", gi_displayPopupCloseTimeSec);
//console.log("★SaveSetting: [" + u + "] = " + ret);
}
//強制リロード値を入力させる
function dispReloadSetting(){
//URLを確認
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
var ret = window.prompt( SPT + "最後に更新があがってきてから" + SPC + "強制リロード発動までの時間" + SPC + SPC + "URL = /" + u + SPC
+ "設定値: " + ((giA_updateIntervalMs[gi_dispMode] /1000) * 2) + "〜7200(sec)" + SPC + "(※不使用時は 0 に設定)", gi_reloadTimeoutSec);
if( ret === null ) return;
ret = Number(ret);
if( ret != 0 && ( ret < ((giA_updateIntervalMs[gi_dispMode] /1000) * 2) || ret > 7200 ) ) return;
//console.log("★InputValue = " + ret);
gi_reloadTimeoutSec = ret;
localStorage.setItem( RELOAD_HEADER + u, ret );
dispPopupMessage("強制リロードまでの待機時間を" + ret + "秒に変更しました", gi_displayPopupCloseTimeSec);
//console.log("★SaveSetting: [" + u + "] = " + ret);
}
//手動更新禁止期間値を入力させる
function dispManualSetting(){
//URLを確認
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
var ret = window.prompt( SPT + "更新リクエスト発行から" + SPC + "次の更新までの禁止時間" + SPC + SPC + "URL = /" + u + SPC
+ "設定値: 5〜60(sec)", gi_manualUpdateIntervalSec);
if( ret === null ) return;
ret = Number(ret);
if( ret < 5 || ret > 60 ) return;
//console.log("★InputValue = " + ret);
gi_manualUpdateIntervalSec = ret;
localStorage.setItem( MANUAL_HEADER + u, ret );
dispPopupMessage("更新リクエストの禁止期間を" + ret + "秒に変更しました", gi_displayPopupCloseTimeSec);
//console.log("★SaveSetting: [" + u + "] = " + ret);
}
//メディアサムネイルの表示サイズとRT&引用RT表示設定を切り替える
function mediaSizeSetting(){
//URLを確認
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
var ret = window.prompt( SPT + "メディアサムネイルの表示サイズ" + SPC +
SIZE_NAME[0] + ", " + SIZE_NAME[1] + ", " + SIZE_NAME[2] + ", " + SIZE_NAME[3] +
SPC + SPC + "URL = /" + u + SPC +
"設定値: 0〜3", gi_mediaSize);
if( ret !== null ){
ret = Number(ret);
if( ret < 0 || ret > 3 ){
//メディア選択変更なし
}else{
//console.log("★InputValue = " + ret);
gi_mediaSize = ret;
//ドキュメントへのモード書き込み ローカル保存もこの関数の中で行われる
dispPopupMessage("メディアサムネイルを" + SIZE_NAME[ret] + "に変更しました", gi_displayPopupCloseTimeSec);
//console.log("★SaveSetting: [" + u + "] = " + ret);
}
}
//RT&引用RT表示設定を切り替える
ret = window.prompt( SPT + "RT非表示・引用RT非表示設定" + SPC + SPC +
NOTRT_NAME[0] + SPC + NOTRT_NAME[1] + SPC + NOTRT_NAME[2] + SPC + NOTRT_NAME[3] +
SPC + SPC + "URL = /" + u + SPC +
"設定値: 0〜3", gi_notDispRt);
if( ret !== null ){
ret = Number(ret);
if( ret < 0 || ret > 3 ){
//RT非表示設定変更なし
}else{
//console.log("★InputValue = " + ret);
gi_notDispRt = ret;
//ドキュメントへのモード書き込み ローカル保存もこの関数の中で行われる
dispPopupMessage("RT・引用RTを" + NOTRT_NAME[ret] + "に変更しました", gi_displayPopupCloseTimeSec);
//console.log("★SaveSetting: [" + u + "] = " + ret);
}
}
//メディアサイズ設定とRT非表示設定をドキュメントに設定・ローカル保存
updateMediaAttribute();
}
*/
//自動更新をON/OFFする(OFFでは強制停止、ONの時はスクロールバーの位置やエディット入力にフォーカスがあるか無いかで判定する従来の動作をする)
function switchAutoButton(){
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
if( gelm_btnAutoOff === null ) return;
if( gi_modeAutoOff == 1 ){
//AUTO = ONにする
gi_modeAutoOff = 0;
if(u.length > 2){
localStorage.setItem( AUTOOFF_HEADER + u, 0 );
dispPopupMessage("自動更新を通常モードに切り替えました", gi_displayPopupCloseTimeSec);
}
}else{
//AUTO = OFFにする
gi_modeAutoOff = 1;
if(u.length > 2){
localStorage.setItem( AUTOOFF_HEADER + u, 1 );
dispPopupMessage("自動更新を強制OFFモードに切り替えました", gi_displayPopupCloseTimeSec);
}
}
}
//短周期タイマの常時動作切り替え
function idleTimerChange(){
if( gi_idleShortTimer == 0 ){
gi_idleShortTimer = 1;
dispPopupMessage("短周期タイマを都度停止するモードに切り替えました", gi_displayPopupCloseTimeSec);
}else{
gi_idleShortTimer = 0;
dispPopupMessage("短周期タイマを常時稼動モードに切り替えました", gi_displayPopupCloseTimeSec);
}
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
if(u.length > 2){
localStorage.setItem( IDLETM_HEADER + u, gi_idleShortTimer );
}
//どちらの設定であっても切り替えられたら短周期タイマを再開させる
if( gtmr_shortTimer === null ){
gtmr_shortTimer = window.setInterval(replaceEtements, gi_shortIntervalMs);
gstr_lastShortStart = new Date();
//console.log("★gtmr_shortTimer: START[idleTimerChange]");
}
}
//ツイート欄の表示非表示切り替え
function swichEditColumn(){
if( gi_dispMode != MODE_HOME ) return;
var e0, v;
e0 = document.querySelectorAll('div[aria-label="ホームタイムライン"] > div:nth-of-type(3)');
if( e0.length > 0 ){
if( ! gi_hideEditControl ){
//表示へ切り替え
e0[0].setAttribute(EDITSW_BLOCK, "0");
e0[0].style.display = null;
gelm_btnEdit.style.color = COLOR_GRAY;
gelm_btnEdit.textContent = " " + BTN_TXT_ED1 + " ";
}else{
//非表示へ切り替え
e0[0].setAttribute(EDITSW_BLOCK, "1");
e0[0].style.display = "none";
gelm_btnEdit.style.color = COLOR_WHITE;
gelm_btnEdit.textContent = " " + BTN_TXT_ED0 + " ";
}
localStorage.setItem( EDITDISP_HEADER, gi_hideEditControl );
//console.log("★setItem" + EDITDISP_HEADER + " = " + gi_hideEditControl);
}
}
//新着件数表示の表示非表示切り替え
function swichDispNumberNewTweet(noMessage){
if( gi_dispMode != MODE_HOME ) return;
var e0, e1;
//要素変更
e0 = document.querySelectorAll('body');
if( e0.length > 0 ){
if( gi_hideNumberNewTweet ){
e0[0].setAttribute(gstr_scrNewTweetAttr, 'false');
e0[0].display = "none";
}else{
e0[0].setAttribute(gstr_scrNewTweetAttr, 'true');
e0[0].display = null;
}
localStorage.setItem( NEWTWDISP_HEADER, gi_hideNumberNewTweet );
if( ! noMessage ){
if( gi_hideNumberNewTweet ){
dispPopupMessage("新着件数の表示をOFFにしました", gi_displayPopupCloseTimeSec);
}else{
dispPopupMessage("新着件数の表示をONにしました", gi_displayPopupCloseTimeSec);
}
}
}
}
//ポップアップのためのエレメントを生成してメッセージを下部に表示する
function dispPopupMessage(msg, tim_sec){
if( gi_displayPopupCloseTimeSec <= 0 ) return;
var e0, e1, e2, e3, e4, e5, e6, e7;
var bg = COLOR_GRAY;
var nowObj, nowTime, endTime;
//複数のポップアップが積み重なるのを許可するため、消去予定時間をエレメントに付加しておく
nowObj = new Date();
nowTime = nowObj.getTime();
endTime = nowTime + (tim_sec * 1000);
//Twitterの色設定に依存するツイートボタン色から背景色を拾ってくる
e7 = document.querySelectorAll('a[data-testid="SideNav_NewTweet_Button"]');
if( e7.length > 0 ){
bg = window.getComputedStyle(e7[0], null).getPropertyValue('background-color');
}
//要らないクラスIDとかありそうだけど、実際ツイート後に出るポップアップの要素をそのままコピー
e0 = document.querySelectorAll('div[id="react-root"] div[id="layers"] > div:nth-of-type(1) > div:nth-of-type(1)');
if( e0.length > 0 ){
e1 = document.createElement("div");
e1.setAttribute("id",POPUP_BLOCK);
e1.setAttribute("class","css-1dbjc4n r-12vffkv");
e1.onclick = function(e){e.stopPropagation(); closePopupMessage(e.target); return false;};
e1.setAttribute(POPUP_ENDTIME, endTime);
e2 = document.createElement("div");
e2.setAttribute("id",POPUP_BLOCK + "-1");
e2.setAttribute("class", "css-1dbjc4n r-1jgb5lz r-633pao r-13qz1uu");
e2.style.backgroundColor = bg;
e1.appendChild(e2);
e3 = document.createElement("div");
e3.setAttribute("id",POPUP_BLOCK + "-2");
e3.setAttribute("class", "css-1dbjc4n r-1awozwy r-18u37iz r-1wtj0ep r-q81ovl r-105ug2t r-o7fkjf r-1i6wzkk");
e3.setAttribute("role", "alert");
e3.setAttribute("data-testid", "toast");
e3.setAttribute("style", "transition-duration: 0ms; transition-timing-function: cubic-bezier(0, 0, 1, 1);");
e2.appendChild(e3);
e4 = document.createElement("div");
e4.setAttribute("id",POPUP_BLOCK + "-3");
e4.setAttribute("class", "css-901oao r-jwli3a r-1wbh5a2 r-1tl8opc r-1b43r93 r-16dba41 r-hjklzo r-bcqeeo r-1qfz7tf r-qvutc0");
e4.setAttribute("dir", "ltr");
e3.appendChild(e4);
e5 = document.createElement("span");
e5.setAttribute("id",POPUP_BLOCK + "-4");
e5.setAttribute("class", "css-901oao css-16my406 r-1tl8opc r-bcqeeo r-qvutc0");
e5.textContent = "[" + toFormatedDateString(nowObj) + "] \r\n" + msg;
e4.appendChild(e5);
e0[0].insertBefore(e1, e0[0].firstElementChild);
window.setTimeout( closePopupMessage, tim_sec * 1000 );
}
}
//ポップアップを消去
function closePopupMessage(obj){
var dt = (new Date()).getTime();
var attrTime;
if( obj != null ){
//console.log("★popupRemoved onClick0 : [" + obj + "]");
while(obj.getAttribute("id") != POPUP_BLOCK){
//console.log("★popupRemoved onClick1 : [" + obj + "] = " + obj.getAttribute("id") );
obj = obj.parentNode;
if( obj == null ) break;
}
obj.remove();
return;
}
//複数スタックを許可するポップアップの終了条件を要素から取得
var e0 = document.querySelectorAll('div[id="' + POPUP_BLOCK + '"]');
for( var i=0; i < e0.length; i++ ){
attrTime = Number(e0[i].getAttribute(POPUP_ENDTIME));
if( dt > attrTime ){
e0[0].remove();
//console.log("★popupRemoved " + dt + " / " + attrTime);
}else{
window.setTimeout( closePopupMessage, 100 );
}
}
}
//コンフィグのためのエレメントを生成してオーバーレイ表示する
function dispSettingMessage(){
var e0, e1, e2, e = [];
var bg = COLOR_GRAY;
var nowObj, nowTime, endTime;
var HTML = "";
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
//Twitterの色設定に依存するツイートボタン色から背景色を拾ってくる
e0 = document.querySelectorAll('a[data-testid="SideNav_NewTweet_Button"]');
if( e0.length > 0 ){
bg = window.getComputedStyle(e0[0], null).getPropertyValue('background-color');
}
HTML += CRLF + "
";
HTML += CRLF + "PseudoTweetDeck Config Setting
";
HTML += CRLF + "Path=" + decodeURIComponent(u) + "
";
HTML += CRLF + "";
//コンフィグ画面を構築
e0 = document.querySelectorAll('div[id="react-root"]');
if( e0.length > 0 ){
//設定起動中のフラグを立てる(強制リロードの回避)
gb_enableSettingWindow = true;
//背景エレメント
e1 = document.createElement("div");
e1.setAttribute("id",SETTING_BLOCK);
e1.style.display = "block";
e1.style.position = "absolute";
e1.style.height = "100%";
e1.style.width = "100%";
e1.style.backgroundColor = bg;
e1.style.color = COLOR_WHITE;
e1.style.zIndex = "999";
e1.style.position = "fixed";
e1.onclick = function(e){e.stopPropagation(); return false;};
e1.onkeydown = function(e){e.stopPropagation(); return false;};
e1.onkeyup = function(e){e.stopPropagation(); return false;};
e1.onkeypress = function(e){e.stopPropagation(); return false;};
e1.onchange = function(e){e.stopPropagation(); return false;};
e2 = document.createElement("div");
e2.style.display = "flex";
e2.style.position = "relative";
e2.style.height = "100%";
e2.style.width = "100%";
e2.style.overflow = "scroll";
e2.insertAdjacentHTML("beforeend", HTML);
e1.appendChild(e2);
e0[0].appendChild(e1);
//テーブルエレメント
e[0] = document.getElementById('ELM_MAIN_TABLE');
e[0].style.minWidth = "390px";
e[0].style.maxWidth = "500px";
e[1] = document.getElementById('ELM_INNER_TABLE');
e[1].style.fontSize = "75%";
//自動モード
e[0] = document.getElementById('ELM_AUTO_OFF_MODE');
e[0].style.width = "95%";
e[0].value = ((gi_modeAutoOff==1)?"OFF":"ON");
e[0].onclick = function(e){
e.stopPropagation();
gi_modeAutoOff = ! gi_modeAutoOff;
e.target.value = ((gi_modeAutoOff==1)?"OFF":"ON");
localStorage.setItem( AUTOOFF_HEADER + u, gi_modeAutoOff );
return false;
};
//短周期タイマ都度停止モード
e[0] = document.getElementById('ELM_SHORT_IDLE_MODE');
e[0].style.width = "95%";
e[0].value = ((gi_idleShortTimer==1)?"IDLE":"ALWAYS");
e[0].onclick = function(e){
e.stopPropagation();
gi_idleShortTimer = ! gi_idleShortTimer;
e.target.value = ((gi_idleShortTimer==1)?"IDLE":"ALWAYS");
localStorage.setItem( IDLETM_HEADER + u, gi_idleShortTimer );
//どちらの設定であっても切り替えられたら短周期タイマを再開させる
if( gtmr_shortTimer === null ){
gtmr_shortTimer = window.setInterval(replaceEtements, gi_shortIntervalMs);
gstr_lastShortStart = new Date();
}
return false;
};
//自動更新インターバル
e[0] = document.getElementById('ELM_INTERVAL_TIME');
e[0].style.width = "50%";
e[0].style.pointerEvents = "none";
e[0].value = giA_updateIntervalMs[gi_dispMode] / 1000;
e[1] = document.getElementById('ELM_INTERVAL_TIME_VALUP');
e[1].style.width = "20%";
e[1].onclick = function(e){e.stopPropagation(); valueUpButton('ELM_INTERVAL_TIME',gi_manualUpdateIntervalSec,3600,u ); return false;};
e[2] = document.getElementById('ELM_INTERVAL_TIME_VALDN');
e[2].style.width = "20%";
e[2].onclick = function(e){e.stopPropagation(); valueDnButton('ELM_INTERVAL_TIME',gi_manualUpdateIntervalSec,3600,u ); return false;};
//強制リロードインターバル
e[0] = document.getElementById('ELM_FORCE_TIME');
e[0].style.width = "50%";
e[0].style.pointerEvents = "none";
e[0].value = gi_reloadTimeoutSec;
e[1] = document.getElementById('ELM_FORCE_TIME_VALUP');
e[1].style.width = "20%";
e[1].onclick = function(e){e.stopPropagation(); valueUpButton('ELM_FORCE_TIME',0,7200,u ); return false;};
e[2] = document.getElementById('ELM_FORCE_TIME_VALDN');
e[2].style.width = "20%";
e[2].onclick = function(e){e.stopPropagation(); valueDnButton('ELM_FORCE_TIME',0,7200,u ); return false;};
//更新禁止期間
e[0] = document.getElementById('ELM_HOLD_TIME');
e[0].style.width = "50%";
e[0].style.pointerEvents = "none";
e[0].value = gi_manualUpdateIntervalSec;
e[1] = document.getElementById('ELM_HOLD_TIME_VALUP');
e[1].style.width = "20%";
e[1].onclick = function(e){e.stopPropagation(); valueUpButton('ELM_HOLD_TIME',5,60,u ); return false;};
e[2] = document.getElementById('ELM_HOLD_TIME_VALDN');
e[2].style.width = "20%";
e[2].onclick = function(e){e.stopPropagation(); valueDnButton('ELM_HOLD_TIME',5,60,u ); return false;};
//メディアサムネイルサイズ
e[0] = document.getElementById('ELM_MEDIA_SIZE');
e[0].style.width = "50%";
e[0].style.pointerEvents = "none";
e[0].value = gi_mediaSize;
e[1] = document.getElementById('ELM_MEDIA_SIZE_VALUP');
e[1].style.width = "20%";
e[1].onclick = function(e){e.stopPropagation(); valueUpButton('ELM_MEDIA_SIZE',0,3,u ); return false;};
e[2] = document.getElementById('ELM_MEDIA_SIZE_VALDN');
e[2].style.width = "20%";
e[2].onclick = function(e){e.stopPropagation(); valueDnButton('ELM_MEDIA_SIZE',0,3,u ); return false;};
//RT&引用RT非表示
e[0] = document.getElementById('ELM_HIDE_RT');
e[0].style.width = "50%";
e[0].style.pointerEvents = "none";
e[0].value = gi_notDispRt;
e[1] = document.getElementById('ELM_HIDE_RT_VALUP');
e[1].style.width = "20%";
e[1].onclick = function(e){e.stopPropagation(); valueUpButton('ELM_HIDE_RT',0,3,u ); return false;};
e[2] = document.getElementById('ELM_HIDE_RT_VALDN');
e[2].style.width = "20%";
e[2].onclick = function(e){e.stopPropagation(); valueDnButton('ELM_HIDE_RT',0,3,u ); return false;};
if( gi_dispMode == MODE_HOME ){
//ツイート欄の表示
e[0] = document.getElementById('ELM_DISP_EDIT');
e[0].style.width = "95%";
e[0].value = ((gi_hideEditControl==1)?"OFF":"ON");
e[0].onclick = function(e){
e.stopPropagation();
gi_hideEditControl = ! gi_hideEditControl;
e.target.value = ((gi_hideEditControl==1)?"OFF":"ON");
swichEditColumn();
return false;
};
//新着件数の表示
e[0] = document.getElementById('ELM_DISP_NEW_TWEET');
e[0].style.width = "95%";
e[0].value = ((gi_hideNumberNewTweet==1)?"OFF":"ON");
e[0].onclick = function(e){
e.stopPropagation();
gi_hideNumberNewTweet = ! gi_hideNumberNewTweet;
e.target.value = ((gi_hideNumberNewTweet==1)?"OFF":"ON");
swichDispNumberNewTweet(true);
return false;
};
}
if( gi_enableReadPointCheckBox ){
//既読マーク背景色切り替え
e[0] = document.getElementById('ELM_BGCOLOR_TYPE');
e[0].style.width = "50%";
e[0].style.pointerEvents = "none";
e[0].value = gi_readCheckedColorMode + 1;
e[1] = document.getElementById('ELM_BGCOLOR_TYPE_VALUP');
e[1].style.width = "20%";
e[1].onclick = function(e){e.stopPropagation(); valueUpButton('ELM_BGCOLOR_TYPE',0,READ_COLOR_CYCLE,u ); return false;};
e[2] = document.getElementById('ELM_BGCOLOR_TYPE_VALDN');
e[2].style.width = "20%";
e[2].onclick = function(e){e.stopPropagation(); valueDnButton('ELM_BGCOLOR_TYPE',0,READ_COLOR_CYCLE,u ); return false;};
}
//全保存データの削除
e[0] = document.getElementById('ELM_ALL_CLEAR');
e[0].onclick = function(e){e.stopPropagation(); deleteAllData(); return false;};
//設定画面を閉じる
e[0] = document.getElementById('ELM_CLOSE');
e[0].style.width = "100px";
e[0].onclick = function(e){e.stopPropagation(); closeSettingWindow(); return false;};
}
}
//コンフィグ数値増減テーブル
const VALUES0 = [0,10,20,30,40,50,60,70,80,90,100,120,150,180,210,240,270,300,350,400,450,500,600,700,800,900,1000,1200,1500,2000,2500,3000,3600,4000,5000,6000,7200];
const VALUES1 = [0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120];
const VALUES2 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,25,27,30,35,40,45,50,55,60];
var VALUES = [];
//コンフィグの増ボタン共通処理
function valueUpButton(tgt, min, max, u){
if( max > VALUES1[VALUES1.length-1] ) VALUES = VALUES0;
else if( max > VALUES2[VALUES2.length-1] ) VALUES = VALUES1;
else VALUES = VALUES2;
var e1 = document.getElementById(tgt);
var val = Number(e1.value);
if( val < min ) val = min;
if( val > max ) val = max;
for( var i=0; i max ) val = max;
e1.value = val;
saveSettingValueFromUpDn(tgt, u, val);
break;
}
}
}
//コンフィグの減ボタン共通処理
function valueDnButton(tgt, min, max, u){
if( max > VALUES1[VALUES1.length-1] ) VALUES = VALUES0;
else if( max > VALUES2[VALUES2.length-1] ) VALUES = VALUES1;
else VALUES = VALUES2;
var e1 = document.getElementById(tgt);
var val = Number(e1.value);
if( val < min ) val = min;
if( val > max ) val = max;
for( var i=VALUES.length; i>0; i-- ){
if( VALUES[i-1] < val && val <= VALUES[i] ){
val = VALUES[i-1];
if( val < min ) val = min;
e1.value = val;
saveSettingValueFromUpDn(tgt, u, val);
break;
}
}
}
//増減ボタンで変更した値の格納・記憶
function saveSettingValueFromUpDn(tgt, u, val){
switch(tgt){
case "ELM_INTERVAL_TIME":
giA_updateIntervalMs[gi_dispMode] = val * 1000;
localStorage.setItem( INTERVAL_HEADER + u, val );
break;
case "ELM_FORCE_TIME":
gi_reloadTimeoutSec = val;
localStorage.setItem( RELOAD_HEADER + u, val );
break;
case "ELM_HOLD_TIME":
gi_manualUpdateIntervalSec = val;
localStorage.setItem( MANUAL_HEADER + u, val );
break;
case "ELM_MEDIA_SIZE":
gi_mediaSize = val;
updateMediaAttribute();
break;
case "ELM_HIDE_RT":
gi_notDispRt = val;
updateMediaAttribute();
break;
case "ELM_BGCOLOR_TYPE":
gi_readCheckedColorMode = val - 1;
rclickReadPoint(false,true);
break;
}
}
//コンフィグ画面を閉じる
function closeSettingWindow(){
var e0 = document.querySelectorAll('div[id="react-root"] div[id="' + SETTING_BLOCK + '"]');
if( e0.length > 0 ){
e0[0].remove();
}
//設定起動中のフラグを落とす(強制リロードの回避終了)
gb_enableSettingWindow = false;
}
//------------------------------
// ローカル保存データの全削除
//------------------------------
function deleteAllData(){
if( window.confirm(" 自動更新スクリプトが保存した\r\n 全ローカルデータを初期しますか?") == false ) return;
var idx;
var imax = window.localStorage.length;
var keys;
var removeCount = 0;
for( idx = imax - 1; idx > -1; idx-- ){
keys = "" + window.localStorage.key(idx);
if( keys.indexOf(INTERVAL_HEADER) == 0 ||
keys.indexOf(AUTOOFF_HEADER) == 0 ||
keys.indexOf(IDLETM_HEADER) == 0 ||
keys.indexOf("PTD_") == 0 ){
window.localStorage.removeItem(keys);
removeCount++;
}
for( var i=0; i < gi_readArticles; i++ ){
if( keys.indexOf(READ_HEADER[i]) == 0 ){
window.localStorage.removeItem(keys);
removeCount++;
}
}
}
window.alert(" " + removeCount + "件のデータを削除しました\r\n リロードします");
window.location.reload();
}
//ヘルプ・設定情報表示ウィンドウ表示
function dispInfoDialog(){
var idx;
var aut = (gi_modeAutoOff) ? "ON" : "OFF";
var sht = (gi_idleShortTimer) ? "OFF" : "ON";
var rth = Math.floor(gi_reloadTimeoutSec / 3600);
var rtm = Math.floor(gi_reloadTimeoutSec % 3600 / 60);
var rts = gi_reloadTimeoutSec % 60;
var rtt = ("0" + rth).slice(-2) + ":" + ("0" + rtm).slice(-2) + ":" + ("0" + rts).slice(-2);
var reb = (gi_reloadTimeoutSec) ? rtt : "----";
var siz = window.innerWidth + "x" + window.innerHeight;
var ntf = (gi_dispMode == MODE_NOTI) ? true : false;
var msg = "";
msg += SPC + "------------------------------------";
if(!ntf){
msg += SPC + "自動更新インターバル = " + giA_updateIntervalMs[gi_dispMode] / 1000 + "(sec)";
msg += SPC + "手動更新操作の禁止期間 = " + gi_manualUpdateIntervalSec + "(sec)";
msg += SPC + "自動更新の強制停止モード = " + aut;
}
msg += SPC + "短周期タイマ常時稼動モード = " + sht;
msg += SPC + "DOM更新受信最終時刻 = " + gstr_lastDomTime;
msg += SPC + "強制再起動までの待機時間 = " + reb;
msg += SPC + "メディアサムネイルの表示 = " + SIZE_NAME[gi_mediaSize];
msg += SPC + "RT&引用RTの表示設定";
msg += SPC + " = " + NOTRT_NAME[gi_notDispRt];
if( gi_dispMode == MODE_HOME ){
msg += SPC + "上部新着件数の表示設定 = " + ( (gi_hideNumberNewTweet) ? "OFF" : "ON" );
}
msg += SPC + "TabSize = " + siz;
msg += SPC + "------------------------------------";
msg += SPC + "情報表示欄";
if(!ntf){
msg += SPC + " : 左クリック=スクロール戻し";
}
if(gi_manualUpdateTriggerL){
msg += SPC + " +手動更新";
}
if(gi_manualUpdateAutoCheckL){
msg += SPC + " +自動既読マーク";
}
if(gi_restartShortTimerL){
msg += SPC + " +短周期タイマ再開";
}
if(gi_clearNewNotificationL && ntf){
msg += SPC + " +新着表示色クリア";
}
msg += SPC + " : 右クリック=スクロール戻し";
if(gi_manualUpdateTriggerR){
msg += SPC + " +手動更新";
}
if(gi_manualUpdateAutoCheckR){
msg += SPC + " +自動既読マーク";
}
if(gi_restartShortTimerR){
msg += SPC + " +短周期タイマ再開";
}
if(gi_clearNewNotificationR && ntf){
msg += SPC + " +新着表示色クリア";
}
msg += SPC + BTN_TXT_HLP + " : 左クリック=ヘルプダイアログの表示";
if(gi_enableReadPointCheckBox && !ntf){
msg += SPC + " : 左クリック=既読情報ダイアログの表示";
}
msg += SPC + BTN_TXT_INT + " : 左クリック=コンフィグ";
msg += SPC + " : 右クリック=コンフィグ";
msg += SPC + BTN_TXT_SRT + " : 左クリック=短周期タイマ切り替え";
msg += SPC + " : 右クリック=コンフィグ";
if(!ntf){
msg += SPC + BTN_TXT_AUT + " : 左クリック=自動更新OFF切り替え";
msg += SPC + " : 右クリック=コンフィグ";
}
if( gi_enableReadPointCheckBox ){
if( gi_readCheckedColorMode > -1 ){
msg += SPC + "チェックボックス : ColorType=[" + gi_readCheckedColorMode + "]";
}else{
msg += SPC + "チェックボックス : 非表示";
}
msg += SPC + " : 左クリック=" + gi_readArticles + "件を既読マーク";
msg += SPC + " : 右クリック=既読マーク背景色切替";
}
if( gi_dispMode == MODE_HOME ){
msg += SPC + BTN_TXT_ED0 + "/" + BTN_TXT_ED1;
msg += SPC + " : 左クリック=ツイート入力欄表示切り替え";
msg += SPC + " : 右クリック=上部の新着件数表示切り替え";
}
msg += SPC + "------------------------------------";
if(!ntf){
msg += SPC + "[COUNT / DOM時刻] , ";
}
msg += SPC + "[Latest / DOM時刻] :";
if(!ntf){
msg += SPC + " 緑:自動更新トリガ有効";
msg += SPC + " 黄:自動更新トリガ直前";
msg += SPC + " 赤:自動更新トリガ発行中";
if( ! gi_enableTimeAutoOff ){
msg += SPC + "[Paused Refresh] :";
}else{
msg += SPC + "[Paused / DOM時刻] :";
}
msg += SPC + " 青:自動更新停止中";
}else{
msg += SPC + " 緑:(通知ページは常時自動動作)";
}
msg += SPC + "表示内容に依存しない色替 :";
msg += SPC + " 水:手動更新の抑制期間中";
msg += SPC + " 紫:強制リロード直前";
msg += SPC + "------------------------------------";
msg += SPC + BTN_TXT_INT + "(明色) / " + BTN_TXT_HLP + "(暗色) :";
msg += SPC + " 基本色は情報表示部に準ずる";
msg += SPC + BTN_TXT_SRT + " :";
msg += SPC + " 短周期タイマ都度停止中";
msg += SPC + " 基本色は情報表示部に準ずる";
msg += SPC + " 灰:短周期タイマ停止中";
msg += SPC + " 短周期タイマ常時稼動中";
msg += SPC + " 基本色は情報表示部に準ずる";
if(!ntf){
msg += SPC + BTN_TXT_AUT + " :";
msg += SPC + " 自動更新の通常動作中";
msg += SPC + " 基本色は情報表示部に準ずる";
msg += SPC + " 自動更新の強制停止中";
msg += SPC + " 灰:自動更新強制停止中";
}
msg += SPC + "------------------------------------";
dispHelpInfoDialogWindow(msg);
}
//情報表示ダイアログ(既読ポイント情報)
function dispReadDialog(){
if( ! gi_enableReadPointCheckBox || gi_readArticles < 0 || gi_dispMode == MODE_NOTI ) return;
var idx, dsp=0;
var msg = "";
msg += SPC + "------------------------------------";
msg += SPC + "既読ポイント数 : " + gi_readArticles;
if( gi_readCheckedColorMode > -1 ){
msg += SPC + "表示タイプ : " + Number(gi_readCheckedColorMode + 1) + " / " + READ_COLOR_CYCLE;
}else{
msg += SPC + "表示タイプ : 非表示中";
}
msg += SPC + "------------------------------------";
for( idx = 0; idx < gi_readArticles; idx++ ){
if( gstrA_readArticleURL[idx] != "" ){
msg += SPC + "既読ポイント" + Number(idx + 1) + ":(" + gstrA_readTimeStamp[idx] + ")";
msg += SPC + gstrA_readArticleURL[idx];
msg += SPC + "------------------------------------";
dsp++;
}}
if( dsp == 0 ){
msg += SPC + "現在既読ポイントは設定されていません";
msg += SPC + "------------------------------------";
}
dispHelpInfoDialogWindow(msg);
}
//ヘルプ・情報表示ウィンドウの表示処理共通部
function dispHelpInfoDialogWindow(msg){
var e0, e1, e2, e3, e4, e5;
var bg = COLOR_GRAY;
var nowObj, nowTime, endTime;
var HTML = "";
var u = window.location.href;
if(u.length < (TWITTER_URL.length + 4)) return;
u = u.replace(TWITTER_URL, "");
//Twitterの色設定に依存するツイートボタン色から背景色を拾ってくる
e0 = document.querySelectorAll('a[data-testid="SideNav_NewTweet_Button"]');
if( e0.length > 0 ){
bg = window.getComputedStyle(e0[0], null).getPropertyValue('background-color');
}
HTML += CRLF + "";
HTML += CRLF + "PseudoTweetDeck Help & Information
";
HTML += CRLF + "Path=" + decodeURIComponent(u) + "
";
HTML += CRLF + "";
//ヘルプ表示画面を構築
e0 = document.querySelectorAll('div[id="react-root"]');
if( e0.length > 0 ){
//設定起動中のフラグを立てる(強制リロードの回避)
gb_enableSettingWindow = true;
//背景エレメント
e1 = document.createElement("div");
e1.setAttribute("id",SETTING_BLOCK);
e1.style.display = "block";
e1.style.position = "absolute";
e1.style.height = "100%";
e1.style.width = "100%";
e1.style.backgroundColor = bg;
e1.style.color = COLOR_WHITE;
e1.style.zIndex = "999";
e1.style.position = "fixed";
e1.onclick = function(e){e.stopPropagation(); return false;};
e1.onkeydown = function(e){e.stopPropagation(); return false;};
e1.onkeyup = function(e){e.stopPropagation(); return false;};
e1.onkeypress = function(e){e.stopPropagation(); return false;};
e1.onchange = function(e){e.stopPropagation(); return false;};
e2 = document.createElement("div");
e2.style.display = "flex";
e2.style.position = "relative";
e2.style.height = "100%";
e2.style.width = "100%";
e2.style.overflow = "scroll";
e2.insertAdjacentHTML("beforeend", HTML);
e1.appendChild(e2);
e0[0].appendChild(e1);
//テーブルエレメント
e3 = document.getElementById('ELM_MAIN_TABLE');
e3.style.minWidth = "390px";
e3.style.maxWidth = "500px";
e4 = document.getElementById('ELM_INNER_TABLE');
e4.style.fontSize = "75%";
//ヘルプ画面を閉じる
e5 = document.getElementById('ELM_CLOSE');
e5.style.width = "100px";
e5.onclick = function(e){e.stopPropagation(); closeSettingWindow(); return false;};
}
}
//メイン処理
(function() {
//初期処理の遅延実行
window.setTimeout(clearElements, gi_initWaitMs);
//短周期処理開始
gtmr_shortTimer = window.setInterval(replaceEtements, gi_shortIntervalMs);
gstr_lastShortStart = new Date();
//console.log("★gtmr_shortTimer: START[FIRST]");
//更新処理開始
window.setInterval(updateTimeline, gi_timerIntervalMs);
})();