├── template ├── blackoutinfo.tpl ├── trends_woeid.tpl ├── thumbnail.tpl ├── timeline_accsel.tpl ├── tlsetting_accsel.tpl ├── tlsetting_member.tpl ├── thumbnail_movie.tpl ├── youtube.tpl ├── messagebox.tpl ├── listmenu_list.tpl ├── usersearch.tpl ├── api_remaining.tpl ├── nowbrowsing.tpl ├── nowbrowsing_list.tpl ├── saved_search.tpl ├── notify_history.tpl ├── tweetbox_image.tpl ├── hash_list.tpl ├── imageviewer.tpl ├── trends_list.tpl ├── rsslist_list.tpl ├── saved_search_list.tpl ├── account_select_list.tpl ├── panellist.tpl ├── notify_incoming.tpl ├── rsslist.tpl ├── searchbox.tpl ├── feed_list.tpl ├── nicovideo.tpl ├── tweetbox_geo.tpl ├── account_select.tpl ├── dmbox.tpl ├── rss.tpl ├── ng_list.tpl ├── tweetbox_reply.tpl ├── notify_new.tpl ├── trends.tpl ├── header_user.tpl ├── follow.tpl ├── api_remaining_list.tpl ├── select_locale.tpl ├── panel.tpl ├── account_list.tpl ├── rss_list.tpl ├── timeline_quote.tpl ├── image.tpl ├── lists.tpl ├── timeline.tpl ├── account.tpl ├── lists_list.tpl ├── timeline_options.tpl ├── impexp.tpl ├── timeline_menu.tpl ├── header.tpl ├── tweetbox.tpl ├── timeline_dm.tpl ├── user_list.tpl ├── accountset.tpl ├── rsssetting.tpl ├── tlsetting.tpl ├── timeline_tweet.tpl └── show.tpl ├── images ├── icon128.png └── verified.png ├── css ├── fonts │ ├── icomoon.eot │ ├── icomoon.ttf │ └── icomoon.woff ├── contents │ ├── youtube.css │ ├── nicovideo.css │ ├── searchbox.css │ ├── notify_history.css │ ├── image.css │ ├── nowbrowsing.css │ ├── dmbox.css │ ├── rsslist.css │ ├── trends.css │ ├── saved_search.css │ ├── accountset.css │ ├── impexp.css │ ├── api_remaining.css │ ├── account.css │ ├── lists.css │ ├── usersearch.css │ ├── follow.css │ ├── rss.css │ ├── tweetbox.css │ ├── cmnsetting.css │ └── show.css ├── license.txt ├── imageviewer.css ├── notification.css ├── jquery-ui.css └── iconfont.css ├── sounds └── notification.ogg ├── README.md ├── .gitattributes ├── .gitignore ├── background.js ├── manifest.json ├── js ├── contents │ ├── nicovideo.js │ ├── youtube.js │ ├── notify_history.js │ ├── nowbrowsing.js │ ├── rsslist.js │ ├── searchbox.js │ ├── saved_search.js │ ├── impexp.js │ ├── dmbox.js │ ├── api_remaining.js │ ├── image.js │ ├── accountset.js │ ├── usersearch.js │ └── rss.js ├── imageviewer.js └── lib │ ├── sha1.js │ └── twemoji.js ├── license.txt └── index.html /template/blackoutinfo.tpl: -------------------------------------------------------------------------------- 1 |
{$msg}
2 | -------------------------------------------------------------------------------- /images/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oken1/kurotwi/HEAD/images/icon128.png -------------------------------------------------------------------------------- /images/verified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oken1/kurotwi/HEAD/images/verified.png -------------------------------------------------------------------------------- /css/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oken1/kurotwi/HEAD/css/fonts/icomoon.eot -------------------------------------------------------------------------------- /css/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oken1/kurotwi/HEAD/css/fonts/icomoon.ttf -------------------------------------------------------------------------------- /css/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oken1/kurotwi/HEAD/css/fonts/icomoon.woff -------------------------------------------------------------------------------- /sounds/notification.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oken1/kurotwi/HEAD/sounds/notification.ogg -------------------------------------------------------------------------------- /template/trends_woeid.tpl: -------------------------------------------------------------------------------- 1 | {$name} 2 | -------------------------------------------------------------------------------- /template/thumbnail.tpl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /template/timeline_accsel.tpl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /template/tlsetting_accsel.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | -------------------------------------------------------------------------------- /template/tlsetting_member.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | -------------------------------------------------------------------------------- /template/thumbnail_movie.tpl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /template/youtube.tpl: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /template/messagebox.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | TEST MESSAGE 5 |
6 |
7 | (i18n_0273) 8 |
9 | -------------------------------------------------------------------------------- /template/listmenu_list.tpl: -------------------------------------------------------------------------------- 1 |
2 | {$item->name}{if $item->mode=='private'}{/if} 3 |
4 | -------------------------------------------------------------------------------- /template/usersearch.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /template/api_remaining.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /template/nowbrowsing.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /template/nowbrowsing_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
{$item->title}
4 |
5 | 6 | {/foreach} 7 | -------------------------------------------------------------------------------- /template/saved_search.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /template/notify_history.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /template/tweetbox_image.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /template/hash_list.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | -------------------------------------------------------------------------------- /template/imageviewer.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | {$thumbnails} 6 |
7 |
8 |
9 |
10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KuroTwi 2 | このアプリケーションはツイッタークライアントです。Google Chrome上で拡張機能として動きます 3 | 4 | # 使い方 5 | 1. Releasesからkurotwi.zipをダウンロードして展開する 6 | 7 | 2. chromeの拡張機能画面でデベロッパーモードをONにして「パッケージ化されていない拡張機能を読み込む」を押す 8 | 9 | 3. manifest.jsonが置いてあるフォルダを指定する 10 | 11 | -------------------------------------------------------------------------------- /template/trends_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
4 |
5 | {$item->name} 6 |
7 |
8 |
9 | {/foreach} 10 | -------------------------------------------------------------------------------- /template/rsslist_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
{$item->param->title}
4 |
(i18n_0223)
5 |
6 | {/foreach} 7 | -------------------------------------------------------------------------------- /template/saved_search_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
{$item->query}
4 |
(i18n_0223)
5 |
6 | {/foreach} 7 | -------------------------------------------------------------------------------- /template/account_select_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
4 | 5 |
6 |
7 | {$item->name} 8 |
9 |
10 | {/foreach} 11 | -------------------------------------------------------------------------------- /template/panellist.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 | {if $item->icon}{/if} 4 | {$item->badge} 5 | {$item->title} 6 |
7 | {/foreach} 8 | -------------------------------------------------------------------------------- /template/notify_incoming.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
8 | (i18n_0009) 9 |
10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /template/rsslist.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | (i18n_0236) 5 |
6 |
7 |
8 |
9 | -------------------------------------------------------------------------------- /css/contents/youtube.css: -------------------------------------------------------------------------------- 1 | /* youtube */ 2 | div.contents.youtube { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | } 9 | 10 | div.contents.youtube iframe { 11 | width: 100%; 12 | height: 100%; 13 | } 14 | -------------------------------------------------------------------------------- /template/searchbox.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | (i18n_0206) 6 | (i18n_0159) 7 |
8 |
9 | -------------------------------------------------------------------------------- /css/contents/nicovideo.css: -------------------------------------------------------------------------------- 1 | /* nicovideo */ 2 | div.contents.nicovideo { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | } 9 | 10 | div.contents.nicovideo iframe { 11 | width: 100%; 12 | height: 100%; 13 | } 14 | -------------------------------------------------------------------------------- /template/feed_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
4 | {$item->title} 5 |
6 |
7 | 8 |
9 |
10 | {/foreach} 11 | -------------------------------------------------------------------------------- /template/nicovideo.tpl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/tweetbox_geo.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | (i18n_0189)({$item->lat},{$item->lng}) 7 |
8 |
9 | 10 |
11 |
12 | -------------------------------------------------------------------------------- /template/account_select.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | {$item->name} 7 |
8 |
9 | 10 |
11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /template/dmbox.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 | {$maxlen} 8 |
9 |
10 | 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /template/rss.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 | 8 |
9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /template/ng_list.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /template/tweetbox_reply.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | {if $item->tooltip} 7 |
(i18n_0151)
8 | {else} 9 |
(i18n_0151)
10 | {/if} 11 |
12 |
13 | 14 |
15 |
16 | -------------------------------------------------------------------------------- /css/contents/searchbox.css: -------------------------------------------------------------------------------- 1 | /* searchbox */ 2 | div.contents.searchbox { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | height: 100%; 9 | } 10 | 11 | /* テキストボックス+検索ボタン */ 12 | #searchbox_box { 13 | width: 100%; 14 | height: 50px; 15 | padding: 4px; 16 | } 17 | 18 | #searchbox_text { 19 | width: auto; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /template/notify_new.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
8 | (i18n_0237) 9 |
10 |
11 | {$user} {$count}(i18n_0204) 12 |
13 |
14 | {$date} 15 |
16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /template/trends.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 16 | -------------------------------------------------------------------------------- /template/header_user.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 | {if $list_id} 4 |
5 | {/if} 6 |
7 | -------------------------------------------------------------------------------- /css/license.txt: -------------------------------------------------------------------------------- 1 | Icon Set: Cuticons -- http://dribbble.com/shots/631056-Cuticons-You-wanted-free-icons-right 2 | License: CC0 -- http://creativecommons.org/publicdomain/zero/1.0/ 3 | 4 | 5 | Icon Set: WebHostingHub Glyphs -- http://www.webhostinghub.com/glyphs/ 6 | License: CC BY 3.0 -- http://creativecommons.org/licenses/by/3.0/ 7 | 8 | 9 | Icon Set: IcoMoon - Free -- http://keyamoon.com/icomoon/ 10 | License: CC BY 3.0 -- http://creativecommons.org/licenses/by/3.0/ -------------------------------------------------------------------------------- /template/follow.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | (i18n_0041) 5 |
6 |
7 | 0 / {$number} 8 |
9 |
10 | 11 | 12 |
13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /template/api_remaining_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 | {if $item != undefined} 3 |
4 |
{$item->title}
5 |
6 |
7 |
8 |
9 |
{$item->remaining}/{$item->limit} ({$item->reset})
10 |
11 |
12 | {/if} 13 | {/foreach} 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /template/select_locale.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | Language 4 |
5 |
6 | 17 |
18 |
19 | OK 20 |
21 |
22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must ends with two \r. 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | chrome.action.onClicked.addListener( function( tab ) { 4 | chrome.tabs.query( { title: 'KuroTwi' }, function( tabs ) { 5 | var multi = false; 6 | 7 | for ( var i = 0 ; i < tabs.length ; i++ ) 8 | { 9 | if ( tabs[i].url.match( /^(chrome|moz)-extension:\/\// ) ) 10 | { 11 | multi = true; 12 | chrome.windows.update( tabs[i].windowId, { focused: true } ); 13 | chrome.tabs.update( tabs[i].id, { active: true } ); 14 | break; 15 | } 16 | } 17 | 18 | if ( multi == false ) 19 | { 20 | chrome.tabs.create( { url: chrome.runtime.getURL( 'index.html' ) } ); 21 | } 22 | } ); 23 | } ); 24 | 25 | -------------------------------------------------------------------------------- /css/contents/notify_history.css: -------------------------------------------------------------------------------- 1 | /* デスクトップ通知履歴 */ 2 | div.contents.notify_history { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: nowrap; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | #notify_history_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | #notify_history_list .notify { 19 | /* border-width: 0 0 1px 0 !important;*/ 20 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 21 | background: none !important; 22 | padding: 6px 0 2px 0 !important; 23 | } 24 | 25 | #notify_history_list .notify:hover { 26 | cursor: default; 27 | } 28 | -------------------------------------------------------------------------------- /css/contents/image.css: -------------------------------------------------------------------------------- 1 | /* image */ 2 | div.contents.image { 3 | overflow: auto; 4 | } 5 | 6 | div.contents.image > div { 7 | position: relative; 8 | } 9 | 10 | div.contents.image > div.imgbtns { 11 | position: absolute; 12 | left: 0; 13 | top: 32px; 14 | } 15 | 16 | div.contents.image .resizebtn { 17 | font-size: 2rem; 18 | opacity: 0.5; 19 | background: #101010; 20 | border: 1px solid #ffffff; 21 | text-align: center; 22 | padding: 2px; 23 | margin: 4px 8px; 24 | z-index: 10; 25 | 26 | } 27 | 28 | div.contents.image .resizebtn:hover { 29 | cursor: pointer; 30 | opacity: 1.0; 31 | } 32 | 33 | div.contents.image video.error { 34 | filter: brightness(0.2) 35 | } 36 | -------------------------------------------------------------------------------- /template/panel.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
{$title}
6 |
7 | (i18n_0188) 8 |
9 |
10 |
11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | -------------------------------------------------------------------------------- /template/account_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
4 | 5 |
6 |
7 |
{$item->name}
8 |
(i18n_0296)
9 |
10 |
11 | 12 | 13 | 14 |
15 |
16 | {/foreach} 17 | -------------------------------------------------------------------------------- /template/rss_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 | {if $item->feedtitle} 3 |
4 |
5 | 8 |
9 |
10 | {else} 11 |
12 |
13 |
14 | {$item->title} 15 |
16 | {if $showdesc} 17 |
18 | {if $item->description}{$item->description}{else}{/if} 19 |
20 | {/if} 21 |
22 |
23 | {/if} 24 | {/foreach} 25 | -------------------------------------------------------------------------------- /template/timeline_quote.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | {if $namedisp==0} 6 | @{$screen_name} {if $name}{$name}{/if} 7 | {else} 8 | {if $name}{$name}{/if} @{$screen_name} 9 | {/if} 10 |
11 |
12 |
13 | 14 |
{$text}
15 |
16 | {foreach item=media_file from=$media} 17 | 18 | {/foreach} 19 |
20 |
21 | -------------------------------------------------------------------------------- /template/image.tpl: -------------------------------------------------------------------------------- 1 |
2 | {if $video} 3 | 8 | {else} 9 | 10 | {/if} 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /template/lists.tpl: -------------------------------------------------------------------------------- 1 |
2 |
(i18n_0171)(25(i18n_0015))
3 |
4 |
(i18n_0244)(100(i18n_0015))
5 |
6 |
(i18n_0217) (i18n_0265)
7 |
(i18n_0222)
8 |
9 |
10 |
11 | 12 | (i18n_0236) 13 |
14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /template/timeline.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | {if $type=='dmrecv'} 6 | (i18n_0251) 7 | {/if} 8 | {if $type=='search'} 9 | 10 |
11 | 12 | 13 | (i18n_0208) 14 |
15 | {/if} 16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /template/account.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | (i18n_0253) 4 | (i18n_0223) 5 | (i18n_0246) 6 | 7 | 8 | 9 |
10 |
11 | PIN: 12 | OK 13 | Cancel 14 |
15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /template/lists_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
4 | 5 |
6 |
7 |
8 | @{$item->user->screen_name}/{$item->name}{if $item->mode=='private'}{/if} 9 |
10 |
11 | {if $item->description}{$item->description}{else}
{/if} 12 |
13 |
14 |
15 | (i18n_0223) 16 | {if $item->toolbarlist}(i18n_0091){else}(i18n_0092){/if} 17 |
18 |
19 | {/foreach} 20 | -------------------------------------------------------------------------------- /template/timeline_options.tpl: -------------------------------------------------------------------------------- 1 | {if $type=='dmrecv' || $type=='dmsent'} 2 | 3 | 4 | {if $type=='dmrecv'} 5 | 6 | {/if} 7 | {else} 8 | 9 | {if $mytweet} 10 | 11 | {/if} 12 | {if !$protected} 13 | 14 | {/if} 15 | 16 |
17 | {/if} 18 | -------------------------------------------------------------------------------- /css/contents/nowbrowsing.css: -------------------------------------------------------------------------------- 1 | /* Now Browsing */ 2 | div.contents.nowbrowsing { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: nowrap; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | #nowbrowsing_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | #nowbrowsing_list div.item { 19 | display: table; 20 | width: 100%; 21 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 22 | padding: 2px 6px 2px 4px; 23 | box-sizing: border-box; 24 | } 25 | 26 | #nowbrowsing_list div.item > div { 27 | display: table-cell; 28 | vertical-align: middle; 29 | } 30 | 31 | #nowbrowsing_list .title { 32 | white-space: normal; 33 | font-weight: bold; 34 | color: var(--panel-text); 35 | padding: 4px; 36 | } 37 | 38 | #nowbrowsing_list .title > span:hover { 39 | cursor: pointer; 40 | opacity: 0.5; 41 | } 42 | -------------------------------------------------------------------------------- /template/impexp.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
(i18n_0053)
4 |
5 |
(i18n_0346)
6 |
7 | (i18n_0230) 8 |
9 |
10 |
11 |
12 |
(i18n_0052)
13 |
14 |
15 | 16 |
17 |
18 | (i18n_0119) 19 | 20 |
21 |
22 |
23 |
(i18n_0346)
24 |
25 | (i18n_0230) 26 |
27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "KuroTwi", 4 | "author": "KEN1", 5 | "version": "2.0.3.1", 6 | "description": "__MSG_manifest_description__", 7 | "default_locale": "en", 8 | "content_security_policy": { 9 | "extension-pages": "script-src 'self' ; object-src 'self'" 10 | }, 11 | 12 | "minimum_chrome_version": "88.0", 13 | 14 | "action": { 15 | "default_icon": "images/icon128.png", 16 | "default_title": "KuroTwi" 17 | }, 18 | 19 | "icons": { 20 | "16": "images/icon128.png", 21 | "32": "images/icon128.png", 22 | "48": "images/icon128.png", 23 | "128": "images/icon128.png" 24 | }, 25 | 26 | "background" : { 27 | "service_worker": "background.js" 28 | }, 29 | 30 | "permissions": [ 31 | "notifications", 32 | "tabs" 33 | ], 34 | 35 | "host_permissions": [ 36 | "https://api.twitter.com/*", 37 | "https://upload.twitter.com/*", 38 | "https://ext.nicovideo.jp/*", 39 | "*://*/*" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /template/timeline_menu.tpl: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /template/header.tpl: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | 7 | 8 |
9 | (i18n_0033) 10 | (i18n_0094) 11 | (i18n_0095) 12 | (i18n_0029) 13 | (i18n_0052)/(i18n_0053) 14 |
15 |
16 | 17 | 18 | 19 | 20 |
21 | -------------------------------------------------------------------------------- /css/contents/dmbox.css: -------------------------------------------------------------------------------- 1 | /* dmbox */ 2 | div.contents.dmbox { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | height: 100%; 9 | } 10 | 11 | /* テキストエリア+ツイートボタン */ 12 | #dmbox_box { 13 | width: 100%; 14 | height: 120px; 15 | padding: 4px; 16 | } 17 | 18 | /* テキストエリア */ 19 | #dmbox_text { 20 | height: 60px; 21 | background: #c7e7d7 !important; 22 | } 23 | 24 | #dmbox_box > div { 25 | display: table; 26 | padding-top: 4px; 27 | box-sizing: border-box; 28 | } 29 | 30 | #dmbox_cnt { 31 | display: table-cell; 32 | width: 30%; 33 | text-align: left; 34 | color: #88ccff; 35 | font-size: 1.4rem; 36 | padding-left: 8px; 37 | vertical-align: middle; 38 | } 39 | 40 | #dmbox_cnt.ng { 41 | color: #ff88cc; 42 | } 43 | 44 | #dmbox_btn { 45 | display: table-cell; 46 | width: 70%; 47 | text-align: right; 48 | vertical-align: middle; 49 | } 50 | 51 | #dmbox_btn #dmsend { 52 | padding: 8px 16px; 53 | } 54 | -------------------------------------------------------------------------------- /js/contents/nicovideo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // ニコニコ動画再生 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.nicovideo = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | 11 | cp.SetIcon( null ); 12 | 13 | //////////////////////////////////////////////////////////// 14 | // 開始処理 15 | //////////////////////////////////////////////////////////// 16 | this.start = function() { 17 | cont.activity( { color: '#ffffff' } ); 18 | 19 | cont.addClass( 'nicovideo' ) 20 | .html( OutputTPL( 'nicovideo', { id: cp.param.id } ) ); 21 | 22 | cp.SetTitle( 'Nicovideo - ' + cp.param['url'], false ); 23 | cont.activity( false ); 24 | }; 25 | 26 | //////////////////////////////////////////////////////////// 27 | // 終了処理 28 | //////////////////////////////////////////////////////////// 29 | this.stop = function() { 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /template/tweetbox.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 | {$maxlen} 8 |
9 |
10 | (i18n_9998) 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 | 20 |
21 |
22 |
23 |
24 |
25 | -------------------------------------------------------------------------------- /css/contents/rsslist.css: -------------------------------------------------------------------------------- 1 | /* RSSパネル一覧 */ 2 | div.contents.rsslist { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: nowrap; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | #rsslist_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | #rsslist_list div.item { 19 | display: table; 20 | width: 100%; 21 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 22 | padding: 2px 6px 2px 4px; 23 | height: 40px; 24 | box-sizing: border-box; 25 | } 26 | 27 | #rsslist_list div.item > div { 28 | display: table-cell; 29 | vertical-align: middle; 30 | } 31 | 32 | #rsslist_list div.item .title span { 33 | display: block; 34 | white-space: normal; 35 | font-weight: bold; 36 | color: var(--panel-text); 37 | padding-right: 2px; 38 | } 39 | 40 | #rsslist_list div.item .title span:hover { 41 | cursor: pointer; 42 | opacity: 0.5; 43 | } 44 | 45 | #rsslist_list div.item .buttons { 46 | text-align: right; 47 | } 48 | -------------------------------------------------------------------------------- /css/contents/trends.css: -------------------------------------------------------------------------------- 1 | /* トレンド */ 2 | div.contents.trends { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: nowrap; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | div.contents.trends .trends_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | div.contents.trends .trends_list .item { 19 | display: table; 20 | width: 100%; 21 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 22 | padding: 2px 6px 2px 4px; 23 | box-sizing: border-box; 24 | } 25 | 26 | div.contents.trends .trends_list .item:hover { 27 | cursor: default; 28 | } 29 | 30 | div.contents.trends .trends_list .item .container { 31 | display: table-cell; 32 | vertical-align: top; 33 | padding: 4px; 34 | } 35 | 36 | div.contents.trends .trends_list .item .container .title > span { 37 | font-weight: bold; 38 | user-select: text; 39 | } 40 | 41 | div.contents.trends .trends_list .item .container .title > span:hover { 42 | opacity: 0.5; 43 | cursor: pointer; 44 | } -------------------------------------------------------------------------------- /css/imageviewer.css: -------------------------------------------------------------------------------- 1 | #imageviewer { 2 | position: fixed; 3 | left: 0; 4 | top: 0; 5 | width: 100vw; 6 | height: 100vh; 7 | z-index: 9400; 8 | background: rgba( 0, 0, 0, 0.5 ); 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: center; 12 | align-items: center; 13 | overflow: hidden; 14 | } 15 | 16 | #imageviewer > div:first-child { 17 | width: 87vw; 18 | height: 87vh; 19 | display: flex; 20 | justify-content: center; 21 | align-items: center; 22 | margin-bottom: 1rem; 23 | } 24 | 25 | #imageviewer img.current { 26 | max-width: 100%; 27 | max-height: 100%; 28 | } 29 | 30 | #imageviewer .thumbnails { 31 | display: flex; 32 | flex-direction: row; 33 | height: 8vh; 34 | } 35 | 36 | #imageviewer .thumbnails img.thumbnail { 37 | width: 8vh; 38 | height: 8vh; 39 | cursor: pointer; 40 | } 41 | 42 | #imageviewer .thumbnails img.thumbnail:not(.current) { 43 | padding: 1vh; 44 | } 45 | 46 | #imageviewer .controls { 47 | margin: 1vh; 48 | } 49 | 50 | #imageviewer .controls > div { 51 | font-size: 2vh; 52 | cursor: pointer; 53 | } 54 | -------------------------------------------------------------------------------- /css/contents/saved_search.css: -------------------------------------------------------------------------------- 1 | /* saved_search */ 2 | div.contents.saved_search { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: nowrap; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | div.contents.saved_search .saved_search_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | div.contents.saved_search .saved_search_list div.item { 19 | display: table; 20 | width: 100%; 21 | padding: 8px 4px 8px 4px; 22 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 23 | box-sizing: border-box; 24 | } 25 | 26 | div.contents.saved_search .saved_search_list div.item > div { 27 | display: table-cell; 28 | vertical-align: middle; 29 | } 30 | 31 | div.contents.saved_search .saved_search_list div.item > .query { 32 | width: 100%; 33 | white-space: normal; 34 | } 35 | 36 | div.contents.saved_search .saved_search_list div.item > .query:hover { 37 | cursor: default; 38 | } 39 | 40 | div.contents.saved_search .saved_search_list div.item > .buttons { 41 | width: 100%; 42 | } 43 | -------------------------------------------------------------------------------- /template/timeline_dm.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 |
8 | {if $namedisp==0} 9 | @{$screen_name} {if $name}{$name}{/if} 10 | {else} 11 | {if $name}{$name}{/if} @{$screen_name} 12 | {/if} 13 | {if $ismutual}{/if} 14 | {if $isfriend}{/if} 15 | {if $isfollower}{/if} 16 |
17 | {$dispdate} 18 |
19 |
20 |
21 |
22 |
{$text}
23 |
24 |
25 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2011 KEN1 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /js/contents/youtube.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // Youtube動画再生 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.youtube = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | 11 | cp.SetIcon( null ); 12 | 13 | //////////////////////////////////////////////////////////// 14 | // 開始処理 15 | //////////////////////////////////////////////////////////// 16 | this.start = function() { 17 | cont.activity( { color: '#ffffff' } ); 18 | 19 | if ( cp.param['url'].match( /https?:\/\/(?:www|m)\.youtube\.com\/watch\?.*v=([^&]+)/ ) || 20 | cp.param['url'].match( /https?:\/\/youtu.be\/([^&]+)/ ) ) 21 | { 22 | var id = RegExp.$1; 23 | 24 | cont.addClass( 'youtube' ) 25 | .html( OutputTPL( 'youtube', { id: id } ) ); 26 | 27 | cp.SetTitle( 'Youtube - ' + cp.param['url'], false ); 28 | cont.activity( false ); 29 | } 30 | }; 31 | 32 | //////////////////////////////////////////////////////////// 33 | // 終了処理 34 | //////////////////////////////////////////////////////////// 35 | this.stop = function() { 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /css/contents/accountset.css: -------------------------------------------------------------------------------- 1 | /* アカウント設定€ */ 2 | div.contents.accountset { 3 | overflow-x: hidden; 4 | overflow-y: auto; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | height: 100%; 9 | } 10 | 11 | #iconchange, #profedit, #reauth { 12 | padding: 8px; 13 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 14 | } 15 | 16 | /* 再認証は保留 */ 17 | #reauth { 18 | display: none; 19 | } 20 | 21 | #profedit { 22 | border-bottom: none; 23 | } 24 | 25 | div.contents.accountset > div > span { 26 | display: block; 27 | margin-bottom: 6px; 28 | } 29 | 30 | #iconimg { 31 | max-width: 48px; 32 | max-height: 48px; 33 | } 34 | 35 | #iconchange > div > div { 36 | display: inline-block; 37 | vertical-align: top; 38 | } 39 | 40 | #iconupload_input { 41 | visibility: hidden; 42 | } 43 | 44 | #iconuploadbox_select { 45 | padding: 0 0 2px 4px; 46 | } 47 | 48 | #iconuploadbox_btn { 49 | padding: 0 4px; 50 | } 51 | 52 | #profedit > div { 53 | margin: 4px 0; 54 | } 55 | 56 | #profedit > div > span { 57 | display: inline-block; 58 | width: 50px; 59 | } 60 | 61 | #profedit > div > input[type=text] { 62 | width: 180px; 63 | } 64 | 65 | #profedit > div > textarea { 66 | margin: 4px 0; 67 | width: 320px; 68 | height: 50px; 69 | } 70 | -------------------------------------------------------------------------------- /css/contents/impexp.css: -------------------------------------------------------------------------------- 1 | /* インポート/エクスポート */ 2 | div.contents.impexp { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | height: 100%; 9 | } 10 | 11 | #impexp { 12 | width: 100%; 13 | } 14 | 15 | #impexp .group { 16 | padding: 8px; 17 | } 18 | 19 | #impexp .group .groupname { 20 | font-weight: bold; 21 | } 22 | 23 | #impexp .group .item { 24 | display: table; 25 | width: 100%; 26 | margin: 0 4px; 27 | vertical-align: middle; 28 | border-bottom: 1px solid #202020; 29 | } 30 | 31 | #impexp .group .item > div { 32 | display: table-cell; 33 | padding: 2px 0; 34 | } 35 | 36 | #impexp .group .item .itemname { 37 | white-space: normal; 38 | } 39 | 40 | #impexp .group .item .buttons { 41 | text-align: right; 42 | padding-right: 4px; 43 | } 44 | 45 | #importfile_select { 46 | display: table; 47 | width: 100%; 48 | white-space: normal; 49 | margin-left: 8px; 50 | margin-top: 4px; 51 | vertical-align: middle; 52 | } 53 | 54 | #importfile_select > div { 55 | display: table-cell; 56 | padding: 2px 0; 57 | } 58 | 59 | #importfile_select > div:last-child { 60 | padding-left: 4px; 61 | white-space: nowrap; 62 | } 63 | 64 | #importfile_input { 65 | visibility: hidden; 66 | } 67 | -------------------------------------------------------------------------------- /template/user_list.tpl: -------------------------------------------------------------------------------- 1 | {foreach item=item from=$items} 2 |
3 |
4 | 5 |
6 |
7 |
8 | {$item->screen_name}{if $item->name} ({$item->name}){/if} 9 | 10 | {if $item->protected}{/if} 11 | {if $item->verified}{/if} 12 | {if $item->ismutual}{/if} 13 | {if $item->isfriend}{/if} 14 | {if $item->isfollower}{/if} 15 |
16 |
17 | (i18n_0083):{$item->count} (i18n_0125):{$item->follow} (i18n_0122):{$item->follower}{if $item->latest_date}
(i18n_0221):{$item->latest_date}{/if} 18 |
19 | {if $item->description} 20 |
21 | {$item->description} 22 |
23 | {/if} 24 |
25 |
26 | {/foreach} 27 | -------------------------------------------------------------------------------- /template/accountset.tpl: -------------------------------------------------------------------------------- 1 |
2 | (i18n_0043) 3 |
4 |
5 | 6 |
7 |
8 |
9 | (i18n_0119)
(i18n_0019)
10 | 11 |
12 |
13 | 14 | (i18n_0050) 15 |
16 |
17 |
18 |
19 |
20 | (i18n_0148) 21 |
22 | (i18n_0281): 23 | (50(i18n_0015)) 24 |
25 |
26 | (i18n_0040): 27 | (100(i18n_0015)) 28 |
29 |
30 | (i18n_0233): 31 | (30(i18n_0015)) 32 |
33 |
34 | (i18n_0227):(160(i18n_0015)) 35 | 36 |
37 |
38 | (i18n_0278) 39 |
40 |
41 | -------------------------------------------------------------------------------- /css/notification.css: -------------------------------------------------------------------------------- 1 | /* デスクトップ通知 */ 2 | .notify { 3 | padding: 4px 0; 4 | word-break: break-all; 5 | word-wrap: break-word; 6 | white-space: normal; 7 | line-height: 1.2rem; 8 | overflow: hidden; 9 | } 10 | 11 | .notify:hover { 12 | cursor: pointer; 13 | } 14 | 15 | .notify .tbl { 16 | display: table; 17 | width: auto; 18 | padding: 1px 4px 4px 4px; 19 | box-sizing: border-box; 20 | } 21 | 22 | .notify .tc { 23 | display: table-cell; 24 | } 25 | 26 | .notify .tc.center { 27 | text-align: center; 28 | } 29 | 30 | .notify .tc.center > span.icon-play { 31 | font-size: 16px; 32 | } 33 | 34 | .notify .icon { 35 | width: 3rem; 36 | text-align: center; 37 | vertical-align: top; 38 | } 39 | 40 | .notify .tc.icon > span { 41 | font-size: 2.25rem; 42 | } 43 | 44 | .notify .tc.icon > span.icon-loop { 45 | color: #86aa65 46 | } 47 | 48 | .notify .tc.icon > span.icon-heart { 49 | color: #dd2e44; 50 | } 51 | 52 | .notify img.normal { 53 | width: 2.25rem; 54 | heigth: 2.25rem; 55 | } 56 | 57 | .notify img.rt { 58 | width: 1.5rem; 59 | heigth: 1.5rem; 60 | } 61 | 62 | .notify img.arrow { 63 | width: 1.5rem; 64 | height: 1.5rem; 65 | margin: 4px 4px; 66 | } 67 | 68 | .notify img.favicon { 69 | position: absolute; 70 | left: 24px; 71 | top: 2px; 72 | width: 12px; 73 | heigth: 12px; 74 | } 75 | 76 | .notify .bold { 77 | font-weight: bold; 78 | } 79 | 80 | .notify .date { 81 | opacity: 0.6; 82 | font-size: 0.8rem; 83 | } 84 | 85 | .notify .rt { 86 | font-size: 0.8rem; 87 | opacity: 0.6; 88 | } 89 | -------------------------------------------------------------------------------- /css/contents/api_remaining.css: -------------------------------------------------------------------------------- 1 | /* API残数 */ 2 | div.contents.api_remaining { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: nowrap; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | div.contents.api_remaining .api_remaining_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | div.contents.api_remaining .api_remaining_list .item { 19 | display: table; 20 | width: 100%; 21 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 22 | padding: 2px 6px 2px 4px; 23 | box-sizing: border-box; 24 | } 25 | 26 | div.contents.api_remaining .api_remaining_list .item:hover { 27 | cursor: default; 28 | } 29 | 30 | div.contents.api_remaining .api_remaining_list .item .api { 31 | display: table-cell; 32 | width: auto; 33 | white-space: normal; 34 | padding: 2px; 35 | } 36 | 37 | div.contents.api_remaining .api_remaining_list .item .limit { 38 | position: relative; 39 | display: table-cell; 40 | width: 150px; 41 | vertical-align: middle; 42 | } 43 | 44 | div.contents.api_remaining .api_remaining_list .item .limit .limit_container { 45 | width: 100%; 46 | height: 16px; 47 | background: -webkit-gradient(linear, left top, right top, from(#bb3355), color-stop(0.25,#eebb55), color-stop(0.9,#33bb55) ); 48 | } 49 | 50 | div.contents.api_remaining .api_remaining_list .item .limit .limit_container .used { 51 | position: absolute; 52 | display: inline-block; 53 | background: var(--panel-background); 54 | height: 100%; 55 | } 56 | 57 | div.contents.api_remaining .api_remaining_list .item .limit .info { 58 | position: absolute; 59 | left: 2px; 60 | top: 2px; 61 | font-size: 0.8rem; 62 | } 63 | -------------------------------------------------------------------------------- /css/contents/account.css: -------------------------------------------------------------------------------- 1 | /* account */ 2 | div.contents.account { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | #account_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | #account_list div.item { 19 | display: table; 20 | width: 100%; 21 | padding: 4px; 22 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 23 | box-sizing: border-box; 24 | } 25 | 26 | #account_list div.item > .icon img { 27 | width: 3rem; 28 | height: 3rem; 29 | } 30 | 31 | #account_list div.item > div { 32 | display: table-cell; 33 | vertical-align: middle; 34 | } 35 | 36 | #account_list div.item > div.icon { 37 | width: 3.2rem; 38 | min-width: 3.2rem; 39 | } 40 | 41 | #account_list div.item > div.icon:hover { 42 | cursor: pointer; 43 | } 44 | 45 | #account_list div.item > div.name { 46 | white-space: normal; 47 | } 48 | 49 | #account_list div.item > div.name > div:first-child > span { 50 | font-weight: bold; 51 | } 52 | 53 | #account_list div.item > div.name > div:first-child > span:hover { 54 | cursor: pointer; 55 | opacity: 0.8; 56 | } 57 | 58 | #account_list div.item > div.name .apilimit { 59 | color: #c0c0c0; 60 | font-size: 0.8rem; 61 | } 62 | 63 | #account_list div.item > div.name .apilimit:hover { 64 | cursor: pointer; 65 | } 66 | 67 | #account_list div.item > div.buttons { 68 | text-align: right; 69 | padding-right: 12px; 70 | } 71 | 72 | #account_list div.item.select { 73 | background: var(--general-highlight); 74 | } 75 | 76 | /* PIN入力 */ 77 | #pin_input { 78 | position: absolute; 79 | left: 0; 80 | top: 0; 81 | z-index: 8900; 82 | border: 1px solid #101010; 83 | background: var(--panel-background); 84 | padding: 0.25rem; 85 | } 86 | 87 | #pin_input_text { 88 | width: 8rem; 89 | padding: 5px; 90 | } -------------------------------------------------------------------------------- /template/rsssetting.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | (i18n_0255) 4 |
5 |
6 |
7 |
(i18n_0180)
8 |
9 |
10 |
11 | (i18n_0075) 12 | 13 |
14 |
15 |
16 |
17 | (i18n_0228) 18 |
19 |
20 | 21 | 22 | 23 | {$param->reload_time}(i18n_0272) 24 |
25 |
26 |
27 |
28 | (i18n_0231) 29 |
30 |
31 | 32 | 33 | 34 | {$param->count}(i18n_0205) 35 |
36 |
37 |
38 |
39 | showdesc==1}checked{/if}> 40 | (i18n_0357) 41 |
42 |
43 |
44 |
(i18n_0121)
45 |
46 |
47 |
48 | URL 49 | 50 | (i18n_0253) 51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | -------------------------------------------------------------------------------- /template/tlsetting.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | (i18n_0255) 4 |
5 |
6 |
7 |
(i18n_0093)
8 |
9 |
10 |
11 | notify_new==1}checked{/if}> 12 | (i18n_0238) 13 |
14 |
15 |
16 | 17 |
(i18n_0077)
18 |
19 |
20 |
21 | (i18n_0240) 22 |
23 |
24 | 25 | 26 | 27 | {$param->reload_time}(i18n_0270) 28 |
29 |
30 |
31 |
32 | (i18n_0191) 33 |
34 |
35 | 36 | 37 | 38 | {$param->get_count}(i18n_0204) 39 |
40 |
41 |
42 |
43 | (i18n_0078) 44 |
45 |
46 | 47 | 48 | 49 | {$param->max_count}(i18n_0204) 50 |
51 |
52 | {if $param->timeline_type=='search'} 53 |
54 |
55 | (i18n_0301) 56 |
57 |
58 |
search_lang==0}checked{/if}>(i18n_0302)
59 |
search_lang==1}checked{/if}>(i18n_0303)
60 |
61 |
62 | {/if} 63 |
64 |
65 | -------------------------------------------------------------------------------- /css/contents/lists.css: -------------------------------------------------------------------------------- 1 | /* リスト一覧 */ 2 | div.contents.lists { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: nowrap; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | div.contents.lists .lists_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | div.contents.lists .lists_list .item { 19 | display: table; 20 | width: 100%; 21 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 22 | padding: 2px 6px 2px 4px; 23 | box-sizing: border-box; 24 | } 25 | 26 | div.contents.lists .lists_list .item:hover { 27 | cursor: default; 28 | } 29 | 30 | div.contents.lists .lists_list .item .icon { 31 | display: table-cell; 32 | width: 3.2rem; 33 | padding-top: 4px; 34 | vertical-align: top; 35 | text-align: center; 36 | } 37 | 38 | div.contents.lists .lists_list .item .icon > img { 39 | width: 3rem; 40 | height: 3rem; 41 | } 42 | 43 | div.contents.lists .lists_list .item .icon > img:hover { 44 | cursor: pointer; 45 | } 46 | 47 | div.contents.lists .lists_list .item .container { 48 | display: table-cell; 49 | vertical-align: top; 50 | padding: 4px; 51 | white-space: normal; 52 | min-width: 150px; 53 | } 54 | 55 | div.contents.lists .lists_list .item .fullname { 56 | padding: 2px 4px; 57 | } 58 | 59 | div.contents.lists .lists_list .item .fullname > span.icon-lock { 60 | vertical-align: bottom; 61 | color: #a4a396; 62 | font-weight: normal; 63 | } 64 | 65 | div.contents.lists .lists_list .item .fullname span:first-child { 66 | font-weight: bold; 67 | } 68 | 69 | div.contents.lists .lists_list .item .fullname span:first-child:hover { 70 | cursor: pointer; 71 | opacity: 0.5; 72 | } 73 | 74 | div.contents.lists .lists_list .item .desc { 75 | font-size: 0.8rem; 76 | opacity: 0.8; 77 | padding: 2px 4px; 78 | } 79 | 80 | div.contents.lists .lists_list .item .buttons { 81 | display: table-cell; 82 | vertical-align: middle; 83 | text-align: right; 84 | } 85 | 86 | /* リスト作成 */ 87 | div.contents.lists .list_create { 88 | position: absolute; 89 | width: 240px; 90 | word-break: break-all; 91 | word-wrap: break-word; 92 | z-index: 8900; 93 | border: 1px solid #101010; 94 | box-shadow: 2px 2px 2px rgba( 0, 0, 0, 0.5 ); 95 | background: var(--panel-background); 96 | padding: 4px; 97 | } 98 | 99 | div.contents.lists .list_create > div { 100 | margin: 6px 4px; 101 | } 102 | 103 | div.contents.lists .list_create > div:last-child { 104 | margin: 12px 4px 2px 4px; 105 | text-align: right; 106 | } 107 | 108 | div.contents.lists .list_create > div .description { 109 | width: 218px; 110 | height: 50px; 111 | } 112 | -------------------------------------------------------------------------------- /css/jquery-ui.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2021-04-01 2 | * http://jqueryui.com 3 | * Includes: draggable.css, core.css, resizable.css, slider.css 4 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 | 6 | .ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0} -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | KuroTwi 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
Loading...
62 | 63 | 64 | 65 | 66 | 67 |
68 | 69 | 70 |
71 | 72 | 73 |
74 | 75 | 76 |
77 | 78 | 79 |
80 |
81 |
82 | 83 | 84 |
85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /js/imageviewer.js: -------------------------------------------------------------------------------- 1 | var imageviewer = { 2 | current: 0, 3 | urls: '', 4 | scrollbar_original: {}, 5 | element: null, 6 | 7 | // カレント表示を変更 8 | changeCurrent: function( index ) { 9 | this.current = index; 10 | 11 | this.element.find( '.thumbnail' ).removeClass( 'current' ).eq( index ).addClass( 'current' ) 12 | this.element.find( '.current' ).attr( 'src', this.urls[this.current] ) 13 | }, 14 | 15 | // キー押下イベント 16 | keyDown: function( e ) { 17 | switch ( e.keyCode ) { 18 | case 27: // ESC 19 | this.close() 20 | break 21 | case 37: // ← 22 | this.changeCurrent( ( this.current > 0 ) ? this.current - 1 : this.urls.length - 1 ) 23 | break 24 | case 39: // → 25 | this.changeCurrent( ( this.current < this.urls.length - 1 ) ? this.current + 1 : 0 ) 26 | break 27 | default: 28 | break 29 | } 30 | }, 31 | 32 | // 画像をパネルで開く 33 | openPanel: function() { 34 | const _cp = new CPanel( null, null, 320, 320 ) 35 | 36 | _cp.SetType( 'image' ) 37 | _cp.SetParam( { 38 | url: this.urls[this.current] 39 | } ) 40 | 41 | _cp.Start() 42 | }, 43 | 44 | // 画像ビューアを閉じる 45 | close: function() { 46 | this.element.off( 'click keydown wheel' ).html( '' ).hide() 47 | 48 | $( 'body' ).css( { 49 | 'overflow-x': this.scrollbar_original.x, 50 | 'overflow-y': this.scrollbar_original.y 51 | } ) 52 | }, 53 | 54 | // 画像ビューアを開く 55 | open: function( element, urls, index ) { 56 | const _iv = this 57 | 58 | this.urls = urls 59 | this.element = element 60 | this.scrollbar_original = { x: $( 'body' ).css( 'overflow-x' ), y: $( 'body' ).css( 'overflow-y' ) } 61 | 62 | $( 'body' ).css( { 63 | 'overflow-x': 'hidden', 64 | 'overflow-y': 'hidden' 65 | } ); 66 | 67 | this.element 68 | .attr( 'tabIndex', 0 ) 69 | .show() 70 | .on( 'click', function() { _iv.close() } ) 71 | .on( 'keydown', function( e ) { _iv.keyDown( e ) } ) 72 | .on( 'wheel', function( e ) { 73 | if ( e.originalEvent.deltaY < 0 ) { 74 | _iv.changeCurrent( ( _iv.current > 0 ) ? _iv.current - 1 : _iv.urls.length - 1 ) 75 | } else { 76 | _iv.changeCurrent( ( _iv.current < _iv.urls.length - 1 ) ? _iv.current + 1 : 0 ) 77 | } 78 | } ) 79 | .focus() 80 | 81 | let thumbnails = '' 82 | 83 | this.urls.forEach( value => { 84 | thumbnails += '' 85 | } ) 86 | 87 | this.element.html( OutputTPL( 'imageviewer', { thumbnails: thumbnails } ) ) 88 | 89 | this.element.find( '.thumbnail' ).on( 'click', function( e ) { 90 | _iv.changeCurrent( _iv.element.find( '.thumbnail' ).index( this ) ) 91 | e.stopPropagation() 92 | } ) 93 | 94 | this.element.find( '.controls' ).find( '.openpanel' ).on( 'click', function( e ) { 95 | _iv.openPanel() 96 | e.stopPropagation() 97 | } ) 98 | 99 | this.changeCurrent( index ) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /js/contents/notify_history.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // デスクトップ通知履歴 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.notify_history = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | var notify_history_list; 11 | var scrollPos = null; 12 | 13 | cp.SetIcon( 'icon-bubble' ); 14 | 15 | //////////////////////////////////////////////////////////// 16 | // リスト部作成 17 | //////////////////////////////////////////////////////////// 18 | var ListMake = function( type ) { 19 | var s = ''; 20 | 21 | for ( var i = g_cmn.notsave.notify_history.length - 1 ; i >= 0 ; i-- ) 22 | { 23 | var assign = {}; 24 | 25 | for ( var arg in g_cmn.notsave.notify_history[i].data ) 26 | { 27 | try { 28 | assign[arg] = decodeURIComponent_space( g_cmn.notsave.notify_history[i].data[arg] ); 29 | } 30 | catch ( err ) 31 | { 32 | assign[arg] = g_cmn.notsave.notify_history[i].data[arg]; 33 | } 34 | } 35 | 36 | s += OutputTPL( 'notify_' + g_cmn.notsave.notify_history[i].type, assign ); 37 | } 38 | 39 | notify_history_list.html( s ) 40 | .scrollTop( 0 ); 41 | 42 | cont.trigger( 'contents_resize' ); 43 | }; 44 | 45 | //////////////////////////////////////////////////////////// 46 | // 開始処理 47 | //////////////////////////////////////////////////////////// 48 | this.start = function() { 49 | //////////////////////////////////////// 50 | // 最小化/設定切替時のスクロール位置 51 | // 保存/復元 52 | //////////////////////////////////////// 53 | cont.on( 'contents_scrollsave', function( e, type ) { 54 | // 保存 55 | if ( type == 0 ) 56 | { 57 | if ( scrollPos == null ) 58 | { 59 | scrollPos = notify_history_list.scrollTop(); 60 | } 61 | } 62 | // 復元 63 | else 64 | { 65 | if ( scrollPos != null ) 66 | { 67 | notify_history_list.scrollTop( scrollPos ); 68 | scrollPos = null; 69 | } 70 | } 71 | } ); 72 | 73 | //////////////////////////////////////// 74 | // リサイズ処理 75 | //////////////////////////////////////// 76 | cont.on( 'contents_resize', function() { 77 | $( '#notify_history_list' ).height( cont.height() - cont.find( '.panel_btns' ).height() - 1 ); 78 | } ); 79 | 80 | // 全体を作成 81 | cont.addClass( 'notify_history' ) 82 | .html( OutputTPL( 'notify_history', {} ) ); 83 | 84 | cp.SetTitle( i18nGetMessage( 'i18n_0094' ), false ); 85 | 86 | notify_history_list = $( '#notify_history_list' ); 87 | 88 | //////////////////////////////////////// 89 | // 更新ボタンクリック 90 | //////////////////////////////////////// 91 | $( '#notify_history_reload' ).click( function( e ) { 92 | // disabledなら処理しない 93 | if ( $( this ).hasClass( 'disabled' ) ) 94 | { 95 | return; 96 | } 97 | 98 | ListMake(); 99 | } ); 100 | 101 | // リスト部作成処理 102 | ListMake(); 103 | }; 104 | 105 | //////////////////////////////////////////////////////////// 106 | // 終了処理 107 | //////////////////////////////////////////////////////////// 108 | this.stop = function() { 109 | }; 110 | } 111 | -------------------------------------------------------------------------------- /template/timeline_tweet.tpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | {if $friends!='-'}{else}{/if} 4 | {if $rt_flg} 5 |
6 | 7 |
8 | {/if} 9 |
10 |
11 |
12 |
13 | {if $namedisp==0} 14 | @{$screen_name} {if $name}{$name}{/if} 15 | {else} 16 | {if $name}{$name}{/if} @{$screen_name} 17 | {/if} 18 | {if $protected}{/if} 19 | {if $verified}{/if} 20 | {if $ismutual}{/if} 21 | {if $isfriend}{/if} 22 | {if $isfollower}{/if} 23 |
24 | {if $rt_flg} 25 | {$dispdate}{$source} 26 | {else} 27 | {$dispdate}{$source} 28 | {/if} 29 |
30 | {if $rtcnt + 1 > 0 || $favcnt > 0} 31 | {if $rtcnt + 1 > 0}:{$rtcnt + 1}{/if} {if $favcnt > 0}:{$favcnt}{/if} 32 | {/if} 33 |
34 |
35 | 36 |
37 |
38 | 39 |
{$text}
40 | 41 | {if $in_reply_to_status_id} 42 |
43 |
44 | {if $in_reply_to_status_id} 45 |
46 | 47 |
48 |
49 | 50 |
51 | {/if} 52 |
53 |
54 | {/if} 55 | 56 |
57 |
58 |
59 | -------------------------------------------------------------------------------- /css/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src: url('fonts/icomoon.eot?ohksvb'); 4 | src: url('fonts/icomoon.eot?ohksvb#iefix') format('embedded-opentype'), 5 | url('fonts/icomoon.ttf?ohksvb') format('truetype'), 6 | url('fonts/icomoon.woff?ohksvb') format('woff'), 7 | url('fonts/icomoon.svg?ohksvb#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | /* use !important to prevent issues with browser extensions that change fonts */ 14 | font-family: 'icomoon' !important; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .icon-volume-off:before { 28 | content: "\f026"; 29 | } 30 | .icon-volume-down:before { 31 | content: "\f027"; 32 | } 33 | .icon-volume-up:before { 34 | content: "\f028"; 35 | } 36 | .icon-earth:before { 37 | content: "\21"; 38 | } 39 | .icon-underline:before { 40 | content: "\22"; 41 | } 42 | .icon-at:before { 43 | content: "\40"; 44 | } 45 | .icon-A:before { 46 | content: "\41"; 47 | } 48 | .icon-arrow_down:before { 49 | content: "\e000"; 50 | } 51 | .icon-arrow-right:before { 52 | content: "\e001"; 53 | } 54 | .icon-arrow-left:before { 55 | content: "\e002"; 56 | } 57 | .icon-play:before { 58 | content: "\e003"; 59 | } 60 | .icon-arrow_up:before { 61 | content: "\e004"; 62 | } 63 | .icon-remove:before { 64 | content: "\e005"; 65 | } 66 | .icon-undo:before { 67 | content: "\e006"; 68 | } 69 | .icon-loop:before { 70 | content: "\e007"; 71 | } 72 | .icon-cog:before { 73 | content: "\e008"; 74 | } 75 | .icon-close:before { 76 | content: "\e009"; 77 | } 78 | .icon-pencil:before { 79 | content: "\e00a"; 80 | } 81 | .icon-file:before { 82 | content: "\e00b"; 83 | } 84 | .icon-star:before { 85 | content: "\e00c"; 86 | } 87 | .icon-expand:before { 88 | content: "\e00d"; 89 | } 90 | .icon-folder-open:before { 91 | content: "\e00e"; 92 | } 93 | .icon-hash:before { 94 | content: "\e00f"; 95 | } 96 | .icon-home:before { 97 | content: "\e010"; 98 | } 99 | .icon-list:before { 100 | content: "\e011"; 101 | } 102 | .icon-lrrev:before { 103 | content: "\e012"; 104 | } 105 | .icon-envelop:before { 106 | content: "\e013"; 107 | } 108 | .icon-image:before { 109 | content: "\e014"; 110 | } 111 | .icon-forward:before { 112 | content: "\e015"; 113 | } 114 | .icon-lock:before { 115 | content: "\e016"; 116 | } 117 | .icon-feed:before { 118 | content: "\e017"; 119 | } 120 | .icon-disk:before { 121 | content: "\e018"; 122 | } 123 | .icon-bubble:before { 124 | content: "\e019"; 125 | } 126 | .icon-twitter:before { 127 | content: "\e01a"; 128 | } 129 | .icon-udrev:before { 130 | content: "\e01b"; 131 | } 132 | .icon-user:before { 133 | content: "\e01c"; 134 | } 135 | .icon-users:before { 136 | content: "\e01d"; 137 | } 138 | .icon-wrench:before { 139 | content: "\e01e"; 140 | } 141 | .icon-search:before { 142 | content: "\e01f"; 143 | } 144 | .icon-heart:before { 145 | content: "\e900"; 146 | } 147 | .icon-resize:before { 148 | content: "\f1ed"; 149 | } 150 | .icon-place:before { 151 | content: "\f220"; 152 | } 153 | .icon-maximize:before { 154 | content: "\f30f"; 155 | } 156 | .icon-redo:before { 157 | content: "\f32b"; 158 | } 159 | -------------------------------------------------------------------------------- /css/contents/usersearch.css: -------------------------------------------------------------------------------- 1 | /* ユーザ検索一覧 */ 2 | div.contents.usersearch { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: normal; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | div.contents.usersearch .usersearch_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | div.contents.usersearch .usersearch_list div.item { 19 | display: table; 20 | width: 100%; 21 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 22 | padding: 2px 6px 2px 4px; 23 | box-sizing: border-box; 24 | } 25 | 26 | div.contents.usersearch .usersearch_list div.item:hover { 27 | cursor: default; 28 | } 29 | 30 | /* アイコン */ 31 | div.contents.usersearch .usersearch_list div.item > .icon { 32 | display: table-cell; 33 | width: 3.2rem; 34 | padding-top: 4px; 35 | vertical-align: top; 36 | text-align: center; 37 | } 38 | 39 | div.contents.usersearch .usersearch_list div.item .icon > img { 40 | width: 3rem; 41 | height: 3rem; 42 | } 43 | 44 | div.contents.usersearch .usersearch_list div.item .icon > img:hover { 45 | cursor: pointer; 46 | } 47 | 48 | div.contents.usersearch .usersearch_list div.item .container { 49 | display: table-cell; 50 | vertical-align: top; 51 | padding: 4px; 52 | } 53 | 54 | div.contents.usersearch .usersearch_list div.item .container .names { 55 | font-size: 0.8rem; 56 | } 57 | 58 | div.contents.usersearch .usersearch_list div.item .container .names .screen_name, 59 | div.contents.usersearch .usersearch_list div.item .container .names .name { 60 | user-select: text; 61 | } 62 | 63 | div.contents.usersearch .usersearch_list div.item .container .names .screen_name { 64 | font-weight: bold; 65 | font-size: 1rem; 66 | } 67 | 68 | div.contents.usersearch .usersearch_list div.item .container .names .screen_name:hover { 69 | cursor: pointer; 70 | opacity: 0.8; 71 | } 72 | 73 | /* 名前 */ 74 | div.contents.usersearch .usersearch_list div.item .container .names .name { 75 | opacity: 0.6; 76 | } 77 | 78 | div.contents.usersearch .usersearch_list div.item .container .names .name img.emoji { 79 | height: 1rem; 80 | width: 1rem; 81 | } 82 | 83 | /* verified */ 84 | div.contents.usersearch .usersearch_list div.item .container .names > img { 85 | vertical-align: middle; 86 | width: 0.8rem; 87 | height: 0.8rem; 88 | padding: 0 2px; 89 | } 90 | 91 | div.contents.usersearch .usersearch_list div.item .container .names > span.icon-lock { 92 | padding: 0 2px; 93 | color: #a4a396; 94 | } 95 | 96 | div.contents.usersearch .usersearch_list div.item .container .names > span.icon-arrow-left { 97 | padding: 0 2px; 98 | color: #4bb3d3; 99 | } 100 | 101 | div.contents.usersearch .usersearch_list div.item .container .names > span.icon-arrow-right { 102 | padding: 0 2px; 103 | color: #db4d4c; 104 | } 105 | 106 | /* ツイート数、フォロー数 */ 107 | div.contents.usersearch .usersearch_list div.item .container .counts { 108 | opacity: 0.6; 109 | font-size: 0.8rem; 110 | padding: 2px 0px; 111 | } 112 | 113 | /* description */ 114 | div.contents.usersearch .usersearch_list div.item .container .desc { 115 | padding: 2px 0px; 116 | user-select: text; 117 | } 118 | 119 | div.contents.usersearch .usersearch_list .readmore { 120 | display: block; 121 | width: 50%; 122 | margin: 8px auto; 123 | text-align: center; 124 | } 125 | 126 | /* sleeping user */ 127 | div.contents.usersearch .usersearch_list div.item.sleeping_user { 128 | backdrop-filter: brightness(75%); 129 | filter:brightness(50%); 130 | } -------------------------------------------------------------------------------- /template/show.tpl: -------------------------------------------------------------------------------- 1 | {if $header} 2 |
3 |
4 |
5 | {if $icon} 6 | 7 | {/if} 8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 | {if $name} 17 |
18 | {$name}{if $protected}{/if}{if $verified}{/if} 19 |
20 | {/if} 21 |
22 |
23 |
24 | @{$screen_name} (ID:{$id}) 25 |
26 |
27 |
28 | {if $description} 29 |
30 | {$description} 31 |
32 | {/if} 33 |
34 |
35 |
36 | {if $location}{$location} {/if}{if $url}{$url}{/if} 37 |
38 |
39 |
40 |
41 |
42 |
43 | {if $hist} 44 |
45 |
(i18n_0038):
{$hist}
46 |
47 | {/if} 48 | {if $latest} 49 |
50 |
(i18n_0221):
{if $latest_date}{$latest_date}
{/if}{$latest}
51 |
52 | {/if} 53 |
54 |
55 | {else} 56 |
57 |
58 | {if $icon} 59 | 60 | {/if} 61 |
62 |
63 | {if $name} 64 |
65 | {$name}{if $protected}{/if}{if $verified}{/if} 66 |
67 | {/if} 68 |
69 | @{$screen_name} (ID:{$id}) 70 |
71 | {if $location} 72 |
73 |
(i18n_0233):
{$location}
74 |
75 | {/if} 76 | {if $url} 77 |
78 |
(i18n_0040):
{$url}
79 |
80 | {/if} 81 | {if $description} 82 |
83 |
(i18n_0227):
{$description}
84 |
85 | {/if} 86 | {if $hist} 87 |
88 |
(i18n_0038):
{$hist}
89 |
90 | {/if} 91 | {if $latest} 92 |
93 |
(i18n_0221):
{if $latest_date}{$latest_date}
{/if}{$latest}
94 |
95 | {/if} 96 |
97 |
98 | {/if} 99 |
100 |
101 |
(i18n_0083)
102 |
{$statuses_count}
103 |
104 |
105 |
(i18n_0125)
106 |
{$friends_count}
107 |
108 |
109 |
(i18n_0122)
110 |
{$followers_count}
111 |
112 |
113 |
(i18n_0054)
114 |
{$favourites_count}
115 |
116 |
117 |
118 | 119 | {if $muting}(i18n_0366){else}(i18n_0360){/if} 120 | {if $blocking}(i18n_0146){else}(i18n_0140){/if} 121 | (i18n_0071) 122 |
123 |
124 | (i18n_0207) 125 |
126 | -------------------------------------------------------------------------------- /css/contents/follow.css: -------------------------------------------------------------------------------- 1 | /* follow */ 2 | div.contents.follow { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: normal; 8 | height: 100%; 9 | } 10 | 11 | /* 件数部 */ 12 | div.contents.follow .panel_btns > div.count { 13 | text-align: right; 14 | padding-right: 8px; 15 | } 16 | 17 | /* リスト部 */ 18 | div.contents.follow .follow_list { 19 | width: 100%; 20 | overflow-y: auto; 21 | overflow-x: hidden; 22 | } 23 | 24 | /* リスト部 */ 25 | div.contents.follow .follow_list { 26 | width: 100%; 27 | overflow-y: auto; 28 | overflow-x: hidden; 29 | } 30 | 31 | div.contents.follow .follow_list div.item { 32 | display: table; 33 | width: 100%; 34 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 35 | padding: 2px 6px 2px 4px; 36 | box-sizing: border-box; 37 | } 38 | 39 | div.contents.follow .follow_list div.item.icon_only { 40 | display: inline; 41 | width: auto; 42 | border-bottom: none; 43 | padding: 0; 44 | } 45 | 46 | div.contents.follow .follow_list div.item:hover { 47 | cursor: default; 48 | } 49 | 50 | /* アイコン */ 51 | div.contents.follow .follow_list div.item > .icon { 52 | display: table-cell; 53 | width: 3.2rem; 54 | padding-top: 4px; 55 | vertical-align: top; 56 | text-align: center; 57 | } 58 | 59 | div.contents.follow .follow_list div.item > .icon.icon_only { 60 | display: inline; 61 | } 62 | 63 | div.contents.follow .follow_list div.item .icon > img { 64 | width: 3rem; 65 | height: 3rem; 66 | } 67 | 68 | div.contents.follow .follow_list div.item .icon > img:hover { 69 | cursor: pointer; 70 | } 71 | 72 | div.contents.follow .follow_list div.item .container { 73 | display: table-cell; 74 | vertical-align: top; 75 | padding: 4px; 76 | } 77 | 78 | div.contents.follow .follow_list div.item .container .names { 79 | font-size: 0.8rem; 80 | } 81 | 82 | div.contents.follow .follow_list div.item .container .names .screen_name, 83 | div.contents.follow .follow_list div.item .container .names .name { 84 | user-select: text; 85 | } 86 | 87 | div.contents.follow .follow_list div.item .container .names .screen_name { 88 | font-weight: bold; 89 | font-size: 1rem; 90 | } 91 | 92 | div.contents.follow .follow_list div.item .container .names .screen_name:hover { 93 | cursor: pointer; 94 | opacity: 0.8; 95 | } 96 | 97 | /* 名前 */ 98 | div.contents.follow .follow_list div.item .container .names .name { 99 | opacity: 0.6; 100 | } 101 | 102 | div.contents.follow .follow_list div.item .container .names .name img.emoji { 103 | height: 1rem; 104 | width: 1rem; 105 | } 106 | 107 | /* verified */ 108 | div.contents.follow .follow_list div.item .container .names > img { 109 | vertical-align: middle; 110 | width: 0.8rem; 111 | height: 0.8rem; 112 | padding: 0 2px; 113 | } 114 | 115 | div.contents.follow .follow_list div.item .container .names > span.icon-lock { 116 | padding: 0 2px; 117 | color: #a4a396; 118 | } 119 | 120 | div.contents.follow .follow_list div.item .container .names > span.icon-arrow-left { 121 | padding: 0 2px; 122 | color: #4bb3d3; 123 | } 124 | 125 | div.contents.follow .follow_list div.item .container .names > span.icon-arrow-right { 126 | padding: 0 2px; 127 | color: #db4d4c; 128 | } 129 | 130 | /* ツイート数、フォロー数 */ 131 | div.contents.follow .follow_list div.item .container .counts { 132 | opacity: 0.6; 133 | font-size: 0.8rem; 134 | padding: 2px 0px; 135 | } 136 | 137 | /* description */ 138 | div.contents.follow .follow_list div.item .container .desc { 139 | padding: 2px 0px; 140 | display: none; 141 | user-select: text; 142 | } 143 | 144 | div.contents.follow .follow_list .readmore { 145 | display: block; 146 | width: 50%; 147 | margin: 8px auto; 148 | text-align: center; 149 | } 150 | 151 | /* sleeping user */ 152 | div.contents.follow .follow_list div.item.sleeping_user { 153 | backdrop-filter: brightness(75%); 154 | filter:brightness(50%); 155 | } -------------------------------------------------------------------------------- /css/contents/rss.css: -------------------------------------------------------------------------------- 1 | /* RSS */ 2 | div.contents.rss { 3 | word-break: break-all; 4 | word-wrap: break-word; 5 | white-space: normal; 6 | overflow-y: hidden; 7 | overflow-x: hidden; 8 | height: 100%; 9 | } 10 | 11 | /* リスト部 */ 12 | div.contents.rss .rss_list { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | div.contents.rss .rss_list .item { 19 | display: table; 20 | width: 100%; 21 | border-bottom: 1px solid rgba( 0, 0, 0, 0.4 ); 22 | padding: 2px 6px 2px 4px; 23 | box-sizing: border-box; 24 | } 25 | 26 | div.contents.rss .rss_list .item.feed { 27 | background-color: #4e4e4e; 28 | } 29 | 30 | div.contents.rss .rss_list .item:hover { 31 | cursor: default; 32 | } 33 | 34 | div.contents.rss .rss_list .item .container { 35 | display: table-cell; 36 | vertical-align: top; 37 | padding: 4px; 38 | } 39 | 40 | div.contents.rss .rss_list .item .title { 41 | padding: 2px 4px; 42 | } 43 | 44 | div.contents.rss .rss_list .item .title .anchor { 45 | font-weight: bold; 46 | user-select: text; 47 | color: var(--panel-text); 48 | } 49 | 50 | div.contents.rss .rss_list .item .title .anchor:hover { 51 | opacity: 0.5; 52 | } 53 | 54 | div.contents.rss .rss_list .item .desc { 55 | font-size: 0.8rem; 56 | color: var(--panel-text); 57 | opacity: 0.8; 58 | padding: 2px 4px; 59 | } 60 | 61 | /* タイムライン設定 */ 62 | div.contents.rss .setting { 63 | overflow-x: hidden; 64 | overflow-y: hidden; 65 | word-break: break-all; 66 | word-wrap: break-word; 67 | white-space: nowrap; 68 | height: 100%; 69 | } 70 | 71 | /* 設定項目部 */ 72 | div.contents.rss .setting .rsssetting_items { 73 | width: 100%; 74 | overflow-y: auto; 75 | overflow-x: hidden; 76 | } 77 | 78 | div.contents.rss .setting .rsssetting_items .kind { 79 | display: table-cell; 80 | padding: 4px 8px; 81 | font-weight: bold; 82 | } 83 | 84 | div.contents.rss .setting .rsssetting_items .kind { 85 | padding: 4px 8px; 86 | font-weight: bold; 87 | } 88 | 89 | div.contents.rss .setting .rsssetting_items .kind:hover { 90 | cursor: pointer; 91 | } 92 | 93 | div.contents.rss .setting .rsssetting_items .kind > span { 94 | padding-right: 2px; 95 | } 96 | 97 | div.contents.rss .setting .rsssetting_items .kinditems { 98 | min-width: 240px; 99 | margin: 2px; 100 | padding: 4px; 101 | border: 1px solid #101010; 102 | white-space: normal; 103 | } 104 | 105 | div.contents.rss .setting .rsssetting_items .group { 106 | margin: 2px; 107 | padding: 4px; 108 | } 109 | 110 | div.contents.rss .setting .rsssetting_items .group > .title { 111 | width: 100%; 112 | margin: 2px; 113 | } 114 | 115 | /* 新着読み込み設定 */ 116 | div.contents.rss .setting .set_reload_time { 117 | width: 50%; 118 | } 119 | 120 | /* フィードごとの取得エントリ設定 */ 121 | div.contents.rss .setting .set_count { 122 | width: 50%; 123 | } 124 | 125 | /* タイトル設定 */ 126 | div.contents.rss .setting .set_title { 127 | width: 50%; 128 | } 129 | 130 | /* URL設定 */ 131 | div.contents.rss .setting .set_feed { 132 | width: 50%; 133 | } 134 | 135 | div.contents.rss .setting .feed_list .item { 136 | display: table; 137 | padding: 2px; 138 | background: #1e1e1e; 139 | box-sizing: border-box; 140 | } 141 | 142 | div.contents.rss .setting .feed_list .item .title { 143 | display: table-cell; 144 | width: 100%; 145 | vertical-align: middle; 146 | padding-left: 2px; 147 | } 148 | 149 | div.contents.rss .setting .feed_list .item .title:hover { 150 | cursor: default; 151 | } 152 | 153 | div.contents.rss .setting .feed_list .item .del { 154 | display: table-cell; 155 | vertical-align: middle; 156 | } 157 | 158 | div.contents.rss .setting .feed_list .item .del:hover { 159 | cursor: pointer; 160 | } 161 | 162 | div.contents.rss .setting .feed_list .item .del span { 163 | width: 12px; 164 | height: 12px; 165 | margin: 2px; 166 | vertical-align: middle; 167 | } 168 | 169 | div.contents.rss iframe { 170 | position: absolute; 171 | width: 0; 172 | height: 0; 173 | } 174 | -------------------------------------------------------------------------------- /css/contents/tweetbox.css: -------------------------------------------------------------------------------- 1 | /* tweetbox */ 2 | div.contents.tweetbox { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | height: 100%; 9 | } 10 | 11 | /* テキストエリア+ツイートボタン */ 12 | #tweetbox_box { 13 | width: 100%; 14 | height: 120px; 15 | padding: 4px; 16 | } 17 | 18 | /* テキストエリア */ 19 | #tweetbox_text { 20 | height: 60px; 21 | } 22 | 23 | #tweetbox_box > div { 24 | display: table; 25 | padding-top: 4px; 26 | box-sizing: border-box; 27 | } 28 | 29 | #tweetbox_cnt { 30 | display: table-cell; 31 | width: 30%; 32 | text-align: left; 33 | color: #88ccff; 34 | font-size: 1.4rem; 35 | padding-left: 8px; 36 | vertical-align: middle; 37 | } 38 | 39 | #tweetbox_cnt.ng { 40 | color: #ff88cc; 41 | } 42 | 43 | #tweetbox_btn { 44 | display: table-cell; 45 | width: 70%; 46 | text-align: right; 47 | vertical-align: middle; 48 | } 49 | 50 | #tweetbox_btn #tweet { 51 | padding: 8px 16px; 52 | } 53 | 54 | #imageattach_input { 55 | visibility: hidden; 56 | } 57 | 58 | /* 返信ツイート */ 59 | #tweetbox_reply { 60 | } 61 | 62 | /* 添付画像 */ 63 | #tweetbox_image { 64 | display: block; 65 | } 66 | 67 | .replyitem { 68 | display: table; 69 | width: 95%; 70 | border: 1px solid rgba( 0, 0, 0, 0.4 ); 71 | padding: 2px; 72 | margin: 0 auto; 73 | margin-bottom: 4px; 74 | box-sizing: border-box; 75 | } 76 | 77 | .imageitem { 78 | display: inline-block; 79 | padding: 2px; 80 | margin: 0 auto; 81 | margin-bottom: 4px; 82 | box-sizing: border-box; 83 | text-align: left; 84 | } 85 | 86 | .replyitem > div { 87 | display: table-cell; 88 | vertical-align: middle; 89 | word-break: break-all; 90 | word-wrap: break-word; 91 | white-space: normal; 92 | } 93 | 94 | .imageitem > div { 95 | display: inline-block; 96 | vertical-align: middle; 97 | word-break: break-all; 98 | word-wrap: break-word; 99 | white-space: normal; 100 | } 101 | 102 | .imageitem > div.del { 103 | vertical-align: top; 104 | } 105 | 106 | /* アイコン */ 107 | .replyitem > div.icon img { 108 | width: 2.25rem; 109 | height: 2.25rem; 110 | margin: 2px; 111 | font-size: 24px; 112 | } 113 | 114 | .imageitem > div.icon img { 115 | width: 3.5rem; 116 | height: 3.5rem; 117 | margin: 2px 0px 0px 4px; 118 | font-size: 24px; 119 | } 120 | 121 | .replyitem > div.icon { 122 | vertical-align: top; 123 | } 124 | 125 | /* 削除ボタン */ 126 | .replyitem > div.del span, .imageitem > div.del span { 127 | width: 1rem; 128 | height: 1rem; 129 | padding-right: 4px; 130 | font-size: 8px; 131 | } 132 | 133 | .replyitem > div.del span:hover, .imageitem > div.del span:hover { 134 | cursor: pointer; 135 | } 136 | 137 | /* 添付画像 */ 138 | .imageitem > div.filename { 139 | padding-left: 4px; 140 | width: 100%; 141 | } 142 | 143 | .imageitem > div.filename > span { 144 | font-size: 0.8rem; 145 | } 146 | 147 | /* 返信 */ 148 | .replyitem > div.reply { 149 | width: 100%; 150 | padding: 4px; 151 | } 152 | 153 | .replyitem > div.reply:hover { 154 | cursor: default; 155 | } 156 | 157 | .replyitem > div.reply > div.screen_name { 158 | font-weight: bold; 159 | padding-bottom: 2px; 160 | } 161 | 162 | .replyitem > div.reply > div.status > span { 163 | font-weight: normal; 164 | font-size: 0.8rem; 165 | opacity: 0.8; 166 | } 167 | 168 | .replyitem > div.reply > div.date { 169 | font-size: 0.8rem; 170 | opacity: 0.8; 171 | } 172 | 173 | div.contents.tweetbox #hash_select .item { 174 | text-align: left; 175 | } 176 | 177 | div.contents.tweetbox #hash_select .item input[type=checkbox] { 178 | margin-right: 4px; 179 | } 180 | 181 | div.contents.tweetbox #hash_select .item.tlhash { 182 | font-size: 0.8rem; 183 | opacity: 0.8; 184 | } 185 | 186 | div.contents.tweetbox #draft_select .item { 187 | text-align: left; 188 | } 189 | 190 | div.contents.tweetbox #draft_select .item span:first-child { 191 | vertical-align: top; 192 | margin-right: 4px; 193 | } 194 | 195 | div.contents.tweetbox #draft_select .item span:first-child.on { 196 | color: #9d1e1e; 197 | } 198 | 199 | div.contents.tweetbox #draft_select .item span:first-child.off { 200 | color: #101010; 201 | } 202 | 203 | div.contents.tweetbox #draft_select #savedraft { 204 | border-bottom: 1px dotted rgba( 0, 0, 0, 0.4 ); 205 | } 206 | -------------------------------------------------------------------------------- /css/contents/cmnsetting.css: -------------------------------------------------------------------------------- 1 | /* 設定 */ 2 | div.contents.cmnsetting { 3 | overflow-x: hidden; 4 | overflow-y: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: nowrap; 8 | height: 100%; 9 | } 10 | 11 | /* 設定項目部 */ 12 | #cmnsetting_items { 13 | width: 100%; 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | } 17 | 18 | #cmnsetting_items .kind { 19 | padding: 4px 8px; 20 | } 21 | 22 | #cmnsetting_items .kind:hover { 23 | cursor: pointer; 24 | } 25 | 26 | #cmnsetting_items .kind > span { 27 | padding-right: 2px; 28 | } 29 | 30 | #cmnsetting_items .kinditems { 31 | min-width: 240px; 32 | margin: 2px; 33 | padding: 4px; 34 | border: 1px solid #101010; 35 | white-space: normal; 36 | } 37 | 38 | #cmnsetting_items .group { 39 | margin: 2px; 40 | padding: 4px; 41 | } 42 | 43 | #cmnsetting_items .group > .title { 44 | width: 100%; 45 | margin: 2px; 46 | } 47 | 48 | #cmnsetting_items .group .disabled_item { 49 | opacity: 0.5; 50 | } 51 | 52 | #cmnsetting_items .name_large { 53 | color: var(--panel-text); 54 | font-weight: bold; 55 | } 56 | 57 | #cmnsetting_items .name_small { 58 | color: var(--panel-text); 59 | opacity: 0.8; 60 | font-size: 0.8rem; 61 | } 62 | 63 | /* フォントサイズ設定 */ 64 | #cset_font_size { 65 | width: 50%; 66 | } 67 | 68 | /* 新着読み込み設定 */ 69 | #cset_reload_time { 70 | width: 50%; 71 | } 72 | 73 | /* 一度に取得するツイート数設定 */ 74 | #cset_get_count { 75 | width: 50%; 76 | } 77 | 78 | /* タイムラインに表示する最大ツイート数設定 */ 79 | #cset_max_count { 80 | width: 50%; 81 | } 82 | 83 | /* 通知音の音量 */ 84 | #cset_notify_sound_volume { 85 | width: 30%; 86 | } 87 | 88 | /* 試聴ボタン */ 89 | #cset_audition { 90 | padding: 4px 8px 2px 8px; 91 | margin-right: 4px; 92 | } 93 | 94 | /* Now Browsing */ 95 | #cset_nowbrowsing_text { 96 | width: 90%; 97 | } 98 | 99 | /* リプライのみ */ 100 | #reponly_str { 101 | display: inline; 102 | } 103 | 104 | #reponly_str.disabled { 105 | opacity: 0.5; 106 | } 107 | 108 | /* NG設定 */ 109 | #csetng_list { 110 | overflow-y: auto; 111 | height: 180px; 112 | border: 1px solid #101010; 113 | } 114 | 115 | #csetng_list > .ngitem { 116 | display: table; 117 | width: 100%; 118 | box-sizing: border-box; 119 | } 120 | 121 | #csetng_list > .ngitem > div { 122 | display: table-cell; 123 | padding: 3px 0; 124 | vertical-align: middle; 125 | text-align: center; 126 | } 127 | 128 | #csetng_list > .ngitem > .ngenable { 129 | width: auto; 130 | } 131 | 132 | #csetng_list > .ngitem > .ngtype { 133 | width: 4em; 134 | } 135 | 136 | #csetng_list > .ngitem > .ngword { 137 | width: auto; 138 | } 139 | 140 | #csetng_list > .ngitem > .ngdel { 141 | width: 24px; 142 | } 143 | 144 | #csetng_list > .ngitem > .ngdel > span { 145 | text-align: center; 146 | margin: 2px 4px; 147 | } 148 | 149 | #csetng_list > .ngitem > .ngdel > span:hover { 150 | cursor: pointer; 151 | } 152 | 153 | #csetng_list > .ngitem > .ngword > input[type='text'] { 154 | width: 90%; 155 | } 156 | 157 | /* ハッシュタグ設定 */ 158 | #csethash_list { 159 | overflow-y: auto; 160 | height: 180px; 161 | border: 1px solid #101010; 162 | } 163 | 164 | #csethash_list > .hashitem { 165 | display: table; 166 | width: 100%; 167 | box-sizing: border-box; 168 | } 169 | 170 | #csethash_list > .hashitem > div { 171 | display: table-cell; 172 | padding: 3px 0; 173 | vertical-align: middle; 174 | text-align: center; 175 | } 176 | 177 | #csethash_list > .hashitem > .hashword { 178 | width: auto; 179 | } 180 | 181 | #csethash_list > .hashitem > .hashdel { 182 | width: 24px; 183 | } 184 | 185 | #csethash_list > .hashitem > .hashdel > span { 186 | text-align: center; 187 | margin: 2px 4px; 188 | } 189 | 190 | #csethash_list > .hashitem > .hashdel > span:hover { 191 | cursor: pointer; 192 | } 193 | 194 | #csethash_list > .hashitem > .hashword > input[type='text'] { 195 | width: 90%; 196 | } 197 | 198 | #csethash_list > .hashitem > .hashword > input[type='text'].ngchar { 199 | background: #a0a0a0; 200 | } 201 | 202 | /* 色の設定 */ 203 | .colorcontainer { 204 | display: table; 205 | width: 100%; 206 | border-collapse: separate; 207 | border-spacing: 0 1px; 208 | } 209 | 210 | .colorcontainer span:first-child { 211 | display: table-cell; 212 | width: 10rem; 213 | padding-left: 1rem; 214 | } 215 | 216 | .colorcontainer input[type='text'] { 217 | width: 6rem; 218 | } 219 | -------------------------------------------------------------------------------- /css/contents/show.css: -------------------------------------------------------------------------------- 1 | /* show */ 2 | div.contents.show { 3 | overflow-y: auto; 4 | overflow-x: hidden; 5 | word-break: break-all; 6 | word-wrap: break-word; 7 | white-space: normal; 8 | } 9 | 10 | div.contents.show .showcontainer { 11 | display: table; 12 | padding: 4px; 13 | margin: 2px auto; 14 | width: 98%; 15 | box-sizing: border-box; 16 | } 17 | 18 | div.contents.show .showcontainer .icon { 19 | display: table-cell; 20 | vertical-align: top; 21 | text-align: center; 22 | } 23 | 24 | div.contents.show .showcontainer .icon img { 25 | max-width: 48px; 26 | max-height: 48px; 27 | } 28 | 29 | div.contents.show .showcontainer .icon img.exp:hover { 30 | cursor: pointer; 31 | } 32 | 33 | div.contents.show .showcontainer .desc { 34 | display: table-cell; 35 | vertical-align: top; 36 | padding: 4px; 37 | } 38 | 39 | div.contents.show .showcontainer .desc > div { 40 | padding: 2px 0; 41 | } 42 | 43 | div.contents.show .showcontainer .desc .name { 44 | display: table; 45 | font-size: 1.2rem; 46 | font-weight: bold; 47 | box-sizing: border-box; 48 | user-select: text; 49 | } 50 | 51 | div.contents.show .showcontainer .desc .screen_name { 52 | display: table; 53 | font-weight: bold; 54 | box-sizing: border-box; 55 | user-select: text; 56 | } 57 | 58 | div.contents.show .showcontainer .desc .screen_name a { 59 | cursor: pointer; 60 | } 61 | 62 | div.contents.show .showcontainer .desc .name span.icon-lock { 63 | vertical-align: bottom; 64 | font-weight: normal; 65 | font-size: 1rem; 66 | color: #a4a396; 67 | } 68 | 69 | div.contents.show .showcontainer .desc .desctbl { 70 | display: table; 71 | width: 100%; 72 | box-sizing: border-box; 73 | } 74 | 75 | div.contents.show .showcontainer .desc .desctbl > div { 76 | display: table-cell; 77 | } 78 | 79 | div.contents.show .showcontainer .desc .desctbl > .desctitle { 80 | width: 110px; 81 | } 82 | 83 | div.contents.show .showcontainer .desc .desctbl > .desccont { 84 | user-select: text; 85 | } 86 | 87 | div.contents.show .followcontainer { 88 | display: table; 89 | padding: 4px; 90 | margin: 0 auto; 91 | box-sizing: border-box; 92 | } 93 | 94 | div.contents.show .followcontainer > div { 95 | display: table-cell; 96 | text-align: center; 97 | padding: 0 8px; 98 | } 99 | 100 | div.contents.show .followcontainer > div > div:last-child { 101 | font-weight: bold; 102 | } 103 | 104 | div.contents.show .buttons { 105 | display: block; 106 | width: 100%; 107 | padding: 4px; 108 | } 109 | 110 | div.contents.show .header { 111 | position: relative; 112 | display: table; 113 | margin: 2px auto; 114 | width: 512px; 115 | height: 256px; 116 | box-sizing: border-box; 117 | } 118 | 119 | div.contents.show .header > div { 120 | display: table; 121 | width: 100%; 122 | box-sizing: border-box; 123 | } 124 | 125 | div.contents.show .header .overlay { 126 | position: absolute; 127 | left: 0px; 128 | top: 96px; 129 | width: 512px; 130 | height: 160px; 131 | background: -webkit-linear-gradient(top,transparent 0,rgba(0, 0, 0, 0.55) 100%); 132 | } 133 | 134 | div.contents.show .header .icon { 135 | display: table-cell; 136 | vertical-align: top; 137 | text-align: center; 138 | padding-top: 20px; 139 | padding-left: 8px; 140 | } 141 | 142 | div.contents.show .header .icon img { 143 | border: 4px solid white; 144 | width: 73px; 145 | height: 73px; 146 | } 147 | 148 | div.contents.show .header .icon img.exp:hover { 149 | cursor: pointer; 150 | } 151 | 152 | div.contents.show .header .desc { 153 | position: absolute; 154 | left: 0px; 155 | bottom: 0px; 156 | width: 512px; 157 | user-select: text; 158 | } 159 | 160 | div.contents.show .header .desc > div { 161 | margin: 2px; 162 | display: table; 163 | width: 100%; 164 | box-sizing: border-box; 165 | } 166 | 167 | div.contents.show .header .desc > div > div { 168 | display: table-cell; 169 | text-align: center; 170 | } 171 | 172 | div.contents.show .header .name { 173 | font-weight: bold; 174 | font-size: 1.2rem; 175 | } 176 | 177 | div.contents.show .header .name > span.icon-lock { 178 | font-weight: normal; 179 | font-size: 1rem; 180 | color: #a4a396; 181 | } 182 | 183 | div.contents.show .header .screen_name a { 184 | font-weight: bold; 185 | cursor: pointer; 186 | } 187 | 188 | div.contents.show .header .description { 189 | padding: 0 20px; 190 | } 191 | 192 | div.contents.show .header .locurl { 193 | } 194 | -------------------------------------------------------------------------------- /js/contents/nowbrowsing.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // Now Browsing 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.nowbrowsing = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | var nowbrowsing_list; 11 | var scrollPos = null; 12 | 13 | cp.SetIcon( 'icon-earth' ); 14 | 15 | //////////////////////////////////////////////////////////// 16 | // リスト部作成 17 | //////////////////////////////////////////////////////////// 18 | var ListMake = function( type ) { 19 | var items = new Array(); 20 | 21 | chrome.tabs.query( { url: '*://*/*' }, function( tabs ) { 22 | for ( var i = 0 ; i < tabs.length ; i++ ) 23 | { 24 | items.push( { 25 | title: escapeHTML( tabs[i].title ), 26 | url: tabs[i].url, 27 | } ); 28 | } 29 | 30 | nowbrowsing_list.html( OutputTPL( 'nowbrowsing_list', { items: items } ) ) 31 | .scrollTop( 0 ); 32 | 33 | //////////////////////////////////////// 34 | // タイトル-URLクリック 35 | //////////////////////////////////////// 36 | nowbrowsing_list.find( 'div.item .title > span' ).click( function( e ) { 37 | var item = $( this ).parent().parent(); 38 | 39 | var text = $( '
' ).html( g_cmn.cmn_param['nowbrowsing_text'] ).text() + item.attr( 'pagetitle' ) + ' - ' + item.attr( 'url' ); 40 | 41 | var pid = IsUnique( 'tweetbox' ); 42 | var left = null; 43 | var top = null; 44 | var width = 324; 45 | 46 | var SetText = function() { 47 | var areatext = $( '#tweetbox_text' ).val(); 48 | var pos = $( '#tweetbox_text' ).get( 0 ).selectionStart; 49 | var bef = areatext.substr( 0, pos ); 50 | var aft = areatext.substr( pos, areatext.length ); 51 | 52 | $( '#tweetbox_text' ).val( bef + text + aft ) 53 | .focus() 54 | .trigger( 'keyup' ); 55 | }; 56 | 57 | // ツイートパネルが開いていない場合は開く 58 | if ( pid == null ) 59 | { 60 | var _cp = new CPanel( left, top, width, 240 ); 61 | _cp.SetType( 'tweetbox' ); 62 | _cp.SetParam( { account_id: '', rep_user: null, hashtag: null } ); 63 | _cp.Start( function() { 64 | if ( $( '#tweetbox_text' ).length ) { 65 | SetText(); 66 | $( '#tweetbox_text' ).SetPos( 'start' ); 67 | } 68 | } ); 69 | } 70 | else 71 | { 72 | SetText(); 73 | } 74 | 75 | e.stopPropagation(); 76 | } ); 77 | 78 | cont.trigger( 'contents_resize' ); 79 | } ); 80 | }; 81 | 82 | //////////////////////////////////////////////////////////// 83 | // 開始処理 84 | //////////////////////////////////////////////////////////// 85 | this.start = function() { 86 | //////////////////////////////////////// 87 | // 最小化/設定切替時のスクロール位置 88 | // 保存/復元 89 | //////////////////////////////////////// 90 | cont.on( 'contents_scrollsave', function( e, type ) { 91 | // 保存 92 | if ( type == 0 ) 93 | { 94 | if ( scrollPos == null ) 95 | { 96 | scrollPos = nowbrowsing_list.scrollTop(); 97 | } 98 | } 99 | // 復元 100 | else 101 | { 102 | if ( scrollPos != null ) 103 | { 104 | nowbrowsing_list.scrollTop( scrollPos ); 105 | scrollPos = null; 106 | } 107 | } 108 | } ); 109 | 110 | //////////////////////////////////////// 111 | // リサイズ処理 112 | //////////////////////////////////////// 113 | cont.on( 'contents_resize', function() { 114 | $( '#nowbrowsing_list' ).height( cont.height() - cont.find( '.panel_btns' ).height() - 1 ); 115 | } ); 116 | 117 | // 全体を作成 118 | cont.addClass( 'nowbrowsing' ) 119 | .html( OutputTPL( 'nowbrowsing', {} ) ); 120 | 121 | cp.SetTitle( i18nGetMessage( 'i18n_0029' ), false ); 122 | 123 | nowbrowsing_list = $( '#nowbrowsing_list' ); 124 | 125 | //////////////////////////////////////// 126 | // タブの更新イベントでリスト更新 127 | //////////////////////////////////////// 128 | chrome.tabs.onUpdated.addListener( ListMake ); 129 | chrome.tabs.onRemoved.addListener( ListMake ); 130 | 131 | //////////////////////////////////////// 132 | // 更新ボタンクリック 133 | //////////////////////////////////////// 134 | $( '#nowbrowsing_reload' ).click( function( e ) { 135 | // disabledなら処理しない 136 | if ( $( this ).hasClass( 'disabled' ) ) 137 | { 138 | return; 139 | } 140 | 141 | cont.trigger( 'reload_timer' ); 142 | ListMake(); 143 | } ); 144 | 145 | // リスト部作成処理 146 | cont.trigger( 'reload_timer' ); 147 | ListMake(); 148 | }; 149 | 150 | //////////////////////////////////////////////////////////// 151 | // 終了処理 152 | //////////////////////////////////////////////////////////// 153 | this.stop = function() { 154 | chrome.tabs.onUpdated.removeListener( ListMake ); 155 | chrome.tabs.onRemoved.removeListener( ListMake ); 156 | }; 157 | } 158 | -------------------------------------------------------------------------------- /js/contents/rsslist.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // RSSパネル一覧 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.rsslist = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | var rsslist_list; 11 | var scrollPos = null; 12 | 13 | cp.SetIcon( 'icon-feed' ); 14 | 15 | //////////////////////////////////////////////////////////// 16 | // リスト部作成 17 | //////////////////////////////////////////////////////////// 18 | var ListMake = function( type ) { 19 | cont.activity( { color: '#ffffff' } ); 20 | 21 | rsslist_list.html( OutputTPL( 'rsslist_list', { items: g_cmn.rss_panel } ) ) 22 | .scrollTop( 0 ); 23 | 24 | //////////////////////////////////////// 25 | // タイトルクリック 26 | //////////////////////////////////////// 27 | rsslist_list.find( 'div.item .title span' ).click( function( e ) { 28 | // disabledなら処理しない 29 | if ( $( this ).hasClass( 'disabled' ) ) 30 | { 31 | return; 32 | } 33 | 34 | var item = $( this ).parent().parent(); 35 | var id = item.attr( 'id' ); 36 | 37 | // 既に開かれている 38 | if ( GetPanel( 'panel_' + id ) != null ) 39 | { 40 | SetFront( $( '#panel_' + id ) ); 41 | } 42 | else 43 | { 44 | var _cp = new CPanel( null, null, 320, 360, id ); 45 | _cp.SetType( 'rss' ); 46 | _cp.SetParam( g_cmn.rss_panel[id].param ); 47 | _cp.Start(); 48 | } 49 | 50 | e.stopPropagation(); 51 | } ); 52 | 53 | //////////////////////////////////////// 54 | // 削除ボタンクリック 55 | //////////////////////////////////////// 56 | rsslist_list.find( 'div.item .removebtn' ).click( function( e ) { 57 | // disabledなら処理しない 58 | if ( $( this ).hasClass( 'disabled' ) ) 59 | { 60 | return; 61 | } 62 | 63 | if ( confirm( i18nGetMessage( 'i18n_0224' ) ) ) 64 | { 65 | var item = $( this ).parent().parent(); 66 | var id = item.attr( 'id' ); 67 | 68 | // 開いている場合は閉じる 69 | if ( GetPanel( 'panel_' + id ) != null ) 70 | { 71 | $( '#panel_' + id ).find( '.close' ).trigger( 'click', [false] ); 72 | } 73 | 74 | delete g_cmn.rss_panel[id]; 75 | ListMake(); 76 | } 77 | 78 | e.stopPropagation(); 79 | } ); 80 | 81 | cont.trigger( 'contents_resize' ); 82 | 83 | cont.activity( false ); 84 | }; 85 | 86 | //////////////////////////////////////////////////////////// 87 | // 開始処理 88 | //////////////////////////////////////////////////////////// 89 | this.start = function() { 90 | //////////////////////////////////////// 91 | // 最小化/設定切替時のスクロール位置 92 | // 保存/復元 93 | //////////////////////////////////////// 94 | cont.on( 'contents_scrollsave', function( e, type ) { 95 | // 保存 96 | if ( type == 0 ) 97 | { 98 | if ( scrollPos == null ) 99 | { 100 | scrollPos = rsslist_list.scrollTop(); 101 | } 102 | } 103 | // 復元 104 | else 105 | { 106 | if ( scrollPos != null ) 107 | { 108 | rsslist_list.scrollTop( scrollPos ); 109 | scrollPos = null; 110 | } 111 | } 112 | } ); 113 | 114 | //////////////////////////////////////// 115 | // リサイズ処理 116 | //////////////////////////////////////// 117 | cont.on( 'contents_resize', function() { 118 | $( '#rsslist_list' ).height( cont.height() - cont.find( '.panel_btns' ).height() - 1 ); 119 | } ); 120 | 121 | // 全体を作成 122 | cont.addClass( 'rsslist' ) 123 | .html( OutputTPL( 'rsslist', {} ) ); 124 | 125 | cp.SetTitle( i18nGetMessage( 'i18n_0032' ), false ); 126 | 127 | rsslist_list = $( '#rsslist_list' ); 128 | 129 | //////////////////////////////////////// 130 | // 新規作成ボタンクリック 131 | //////////////////////////////////////// 132 | $( '#rsslist_create' ).click( function( e ) { 133 | // disabledなら処理しない 134 | if ( $( this ).hasClass( 'disabled' ) ) 135 | { 136 | return; 137 | } 138 | 139 | var _cp = new CPanel( null, null, 320, 360 ); 140 | _cp.SetType( 'rss' ); 141 | _cp.SetParam( { title: 'RSS', urls: [], reload_time: 15, count: 10 } ); 142 | _cp.Start( function() { 143 | $( '#' + _cp.id ).find( 'div.titlebar' ).find( '.setting' ).trigger( 'click' ); 144 | 145 | var _id = _cp.id.replace( /^panel_/, '' ); 146 | g_cmn.rss_panel[_id] = { 147 | id: _id, 148 | param: _cp.param, 149 | }; 150 | 151 | ListMake(); 152 | } ); 153 | 154 | e.stopPropagation(); 155 | } ); 156 | 157 | //////////////////////////////////////// 158 | // 更新ボタンクリック 159 | //////////////////////////////////////// 160 | $( '#rsslist_reload' ).click( function( e ) { 161 | // disabledなら処理しない 162 | if ( $( this ).hasClass( 'disabled' ) ) 163 | { 164 | return; 165 | } 166 | 167 | ListMake(); 168 | } ); 169 | 170 | // リスト部作成処理 171 | ListMake(); 172 | }; 173 | 174 | //////////////////////////////////////////////////////////// 175 | // 終了処理 176 | //////////////////////////////////////////////////////////// 177 | this.stop = function() { 178 | }; 179 | } 180 | -------------------------------------------------------------------------------- /js/contents/searchbox.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // 検索 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.searchbox = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | 11 | cp.SetIcon( 'icon-search' ); 12 | 13 | //////////////////////////////////////////////////////////// 14 | // プルダウンメニューを作成 15 | //////////////////////////////////////////////////////////// 16 | function MakePullDown() 17 | { 18 | var s = ''; 19 | 20 | if ( g_cmn.account[cp.param['account_id']].notsave.saved_search ) 21 | { 22 | for ( var i = 0, _len = g_cmn.account[cp.param['account_id']].notsave.saved_search.length ; i < _len ; i++ ) 23 | { 24 | s += '
' + escapeHTML( g_cmn.account[cp.param['account_id']].notsave.saved_search[i] ) + '
'; 25 | } 26 | } 27 | 28 | var pulldown = $( '#searchbox_box' ).find( '.pulldown' ); 29 | 30 | pulldown.html( s ); 31 | 32 | if ( s == '' ) 33 | { 34 | pulldown.hide(); 35 | } 36 | } 37 | 38 | //////////////////////////////////////////////////////////// 39 | // 開始処理 40 | //////////////////////////////////////////////////////////// 41 | this.start = function() { 42 | cont.addClass( 'searchbox' ) 43 | .html( OutputTPL( 'searchbox', {} ) ); 44 | 45 | cp.SetTitle( i18nGetMessage( 'i18n_0206' ), false ); 46 | 47 | $( '#searchbox_box' ).find( '.btn' ).addClass( 'disabled' ); 48 | 49 | //////////////////////////////////////// 50 | // リサイズ処理 51 | //////////////////////////////////////// 52 | cont.on( 'contents_resize', function() { 53 | $( '#searchbox_text' ).width( p.width() - 34 - $( '#search' ).outerWidth() - $( '#usersearch' ).outerWidth() ); 54 | $( '#searchbox_box' ).find( '.pulldown' ).width( $( '#searchbox_text' ).width() ); 55 | } ); 56 | 57 | cont.trigger( 'contents_resize' ); 58 | 59 | //////////////////////////////////////// 60 | // アカウント選択変更 61 | //////////////////////////////////////// 62 | cont.on( 'account_changed', function() { 63 | MakePullDown(); 64 | } ); 65 | 66 | //////////////////////////////////////// 67 | // アカウント情報更新 68 | //////////////////////////////////////// 69 | cont.on( 'account_update', function() { 70 | // アカウントが0件の場合はパネルを閉じる 71 | if ( AccountCount() == 0 ) 72 | { 73 | // 検索パネルを閉じる 74 | p.find( '.close' ).trigger( 'click', [false] ); 75 | return; 76 | } 77 | else 78 | { 79 | AccountSelectMake( cp ); 80 | cont.trigger( 'account_changed' ); 81 | } 82 | } ); 83 | 84 | cont.trigger( 'account_update' ); 85 | 86 | //////////////////////////////////////// 87 | // 検索ボタンクリック処理 88 | //////////////////////////////////////// 89 | $( '#search' ).click( function( e ) { 90 | // disabledなら処理しない 91 | if ( $( this ).hasClass( 'disabled' ) ) 92 | { 93 | return; 94 | } 95 | 96 | // ツイートのURLの場合、そのツイートをパネルで開く 97 | if ( $( '#searchbox_text' ).val().match( /https:\/\/twitter\.com\/([0-9a-zA-Z_]+)\/status\/(\d+)/ ) ) 98 | { 99 | var screen_name = RegExp.$1; 100 | var status_id = RegExp.$2; 101 | 102 | var _cp = new CPanel( null, null, 360, 240 ); 103 | _cp.SetType( 'timeline' ); 104 | _cp.SetParam( { 105 | account_id: cp.param['account_id'], 106 | timeline_type: 'perma', 107 | screen_name: screen_name, 108 | status_id: status_id, 109 | reload_time: g_cmn.cmn_param['reload_time'], 110 | } ); 111 | _cp.Start(); 112 | 113 | return false; 114 | } 115 | 116 | OpenSearchResult( $( '#searchbox_text' ).val(), cp.param['account_id'] ); 117 | e.stopPropagation(); 118 | } ); 119 | 120 | //////////////////////////////////////// 121 | // ユーザ検索ボタンクリック処理 122 | //////////////////////////////////////// 123 | $( '#usersearch' ).click( function( e ) { 124 | // disabledなら処理しない 125 | if ( $( this ).hasClass( 'disabled' ) ) 126 | { 127 | return; 128 | } 129 | 130 | var _cp = new CPanel( null, null, 320, 300 ); 131 | _cp.SetType( 'usersearch' ); 132 | _cp.SetParam( { 133 | account_id: cp.param['account_id'], 134 | q: $( '#searchbox_text' ).val(), 135 | } ); 136 | _cp.Start(); 137 | 138 | e.stopPropagation(); 139 | } ); 140 | 141 | //////////////////////////////////////// 142 | // 入力文字数によるボタン制御 143 | //////////////////////////////////////// 144 | $( '#searchbox_text' ).on( 'keyup change', function() { 145 | var slen = $( this ).val().length; 146 | 147 | if ( slen > 0 ) 148 | { 149 | $( '#searchbox_box' ).find( '.btn' ).removeClass( 'disabled' ); 150 | } 151 | else 152 | { 153 | $( '#searchbox_box' ).find( '.btn' ).addClass( 'disabled' ); 154 | } 155 | } ); 156 | 157 | $( '#searchbox_text' ).focus(); 158 | 159 | //////////////////////////////////////// 160 | // テキストボックスクリック 161 | //////////////////////////////////////// 162 | $( '#searchbox_text' ).click( function( e ) { 163 | var pulldown = $( this ).parent().find( '.pulldown' ); 164 | 165 | if ( pulldown.css( 'display' ) == 'none' ) 166 | { 167 | if ( pulldown.find( 'div.item' ).length ) 168 | { 169 | pulldown.show(); 170 | } 171 | } 172 | else 173 | { 174 | pulldown.hide(); 175 | } 176 | 177 | e.stopPropagation(); 178 | } ); 179 | 180 | //////////////////////////////////////// 181 | // プルダウン選択 182 | //////////////////////////////////////// 183 | $( '#searchbox_box' ).find( 'div.pulldown' ).on( 'click', '> div.item', function( e ) { 184 | $( '#searchbox_text' ).val( $( this ).text() ) 185 | .trigger( 'keyup' ) 186 | .focus(); 187 | 188 | $( this ).parent().hide(); 189 | 190 | e.stopPropagation(); 191 | } ); 192 | 193 | //////////////////////////////////////// 194 | // Enterで検索実行 195 | //////////////////////////////////////// 196 | $( '#searchbox_text' ).keypress( function( e ) { 197 | if ( e.keyCode == 13 ) 198 | { 199 | $( '#search' ).trigger( 'click' ); 200 | } 201 | } ); 202 | }; 203 | 204 | //////////////////////////////////////////////////////////// 205 | // 終了処理 206 | //////////////////////////////////////////////////////////// 207 | this.stop = function() { 208 | }; 209 | } 210 | -------------------------------------------------------------------------------- /js/contents/saved_search.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // 検索メモ一覧 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.saved_search = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | var scrollPos = null; 11 | 12 | cp.SetIcon( 'icon-search' ); 13 | 14 | //////////////////////////////////////////////////////////// 15 | // リスト部作成 16 | //////////////////////////////////////////////////////////// 17 | var ListMake = function() { 18 | var param = { 19 | type: 'GET', 20 | url: ApiUrl( '1.1' ) + 'saved_searches/list.json', 21 | data: { 22 | }, 23 | }; 24 | 25 | var items = new Array(); 26 | 27 | cont.activity( { color: '#ffffff' } ); 28 | 29 | SendRequest( 30 | { 31 | action: 'oauth_send', 32 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 33 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 34 | param: param, 35 | id: cp.param['account_id'], 36 | }, 37 | function( res ) 38 | { 39 | g_cmn.account[cp.param['account_id']].notsave.saved_search = []; 40 | 41 | if ( res.status == 200 ) 42 | { 43 | for ( var i = 0, _len = res.json.length ; i < _len ; i++ ) 44 | { 45 | g_cmn.account[cp.param['account_id']].notsave.saved_search.push( res.json[i].query ); 46 | 47 | items.push( { 48 | id: res.json[i].id_str, 49 | query: escapeHTML( res.json[i].query ), 50 | } ); 51 | } 52 | 53 | cont.find( '.saved_search_list' ).html( OutputTPL( 'saved_search_list', { items: items } ) ); 54 | 55 | // 検索パネルを開いている場合はプルダウン更新 56 | var pid = IsUnique( 'searchbox' ); 57 | 58 | if ( pid != null ) 59 | { 60 | $( '#' + pid ).find( 'div.contents' ).trigger( 'account_changed' ); 61 | } 62 | 63 | cont.trigger( 'contents_resize' ); 64 | 65 | //////////////////////////////////////// 66 | // 削除ボタンクリック処理 67 | //////////////////////////////////////// 68 | cont.find( '.saved_search_list' ).find( 'div.item .delbtn' ).click( function( e ) { 69 | // disabledなら処理しない 70 | if ( $( this ).hasClass( 'disabled' ) ) 71 | { 72 | return; 73 | } 74 | 75 | var query = $( this ).parent().parent().find( '.query' ); 76 | 77 | var conf = confirm( i18nGetMessage( 'i18n_0185', [query.attr( 'query' )] ) ); 78 | 79 | if ( conf ) 80 | { 81 | var param = { 82 | type: 'POST', 83 | url: ApiUrl( '1.1' ) + 'saved_searches/destroy/' + query.attr( 'sid' ) + '.json', 84 | data: { 85 | }, 86 | }; 87 | 88 | Blackout( true ); 89 | $( '#blackout' ).activity( { color: '#808080', width: 8, length: 14 } ); 90 | 91 | SendRequest( 92 | { 93 | action: 'oauth_send', 94 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 95 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 96 | param: param, 97 | id: cp.param['account_id'] 98 | }, 99 | function( res ) 100 | { 101 | if ( res.status == 200 ) 102 | { 103 | ListMake(); 104 | } 105 | else 106 | { 107 | ApiError( i18nGetMessage( 'i18n_0225' ), res ); 108 | } 109 | 110 | Blackout( false ); 111 | $( '#blackout' ).activity( false ); 112 | } 113 | ); 114 | } 115 | 116 | e.stopPropagation(); 117 | } ); 118 | } 119 | else 120 | { 121 | ApiError( i18nGetMessage( 'i18n_0209' ), res ); 122 | } 123 | 124 | $( 'panel' ).find( 'div.contents' ).trigger( 'api_remaining_update', [cp.param['account_id']] ); 125 | cont.activity( false ); 126 | } 127 | ); 128 | }; 129 | 130 | //////////////////////////////////////////////////////////// 131 | // 開始処理 132 | //////////////////////////////////////////////////////////// 133 | this.start = function() { 134 | //////////////////////////////////////// 135 | // 最小化/設定切替時のスクロール位置 136 | // 保存/復元 137 | //////////////////////////////////////// 138 | cont.on( 'contents_scrollsave', function( e, type ) { 139 | // 保存 140 | if ( type == 0 ) 141 | { 142 | if ( scrollPos == null ) 143 | { 144 | scrollPos = cont.find( '.saved_search_list' ).scrollTop(); 145 | } 146 | } 147 | // 復元 148 | else 149 | { 150 | if ( scrollPos != null ) 151 | { 152 | cont.find( '.saved_search_list' ).scrollTop( scrollPos ); 153 | scrollPos = null; 154 | } 155 | } 156 | } ); 157 | 158 | //////////////////////////////////////// 159 | // リサイズ処理 160 | //////////////////////////////////////// 161 | cont.on( 'contents_resize', function() { 162 | cont.find( '.saved_search_list' ).height( cont.height() - cont.find( '.panel_btns' ).height() - 1 ); 163 | } ); 164 | 165 | //////////////////////////////////////// 166 | // このパネルを開いたアカウントが 167 | // 削除された場合 168 | //////////////////////////////////////// 169 | var AccountAliveCheck = function() { 170 | if ( g_cmn.account[cp.param['account_id']] == undefined ) 171 | { 172 | // パネルを閉じる 173 | p.find( '.close' ).trigger( 'click', [false] ); 174 | return false; 175 | } 176 | 177 | return true; 178 | }; 179 | 180 | //////////////////////////////////////// 181 | // アカウント情報更新 182 | //////////////////////////////////////// 183 | cont.on( 'account_update', function() { 184 | AccountAliveCheck(); 185 | } ); 186 | 187 | if ( !AccountAliveCheck() ) 188 | { 189 | return; 190 | } 191 | 192 | // 全体を作成 193 | cont.addClass( 'saved_search' ) 194 | .html( OutputTPL( 'saved_search', {} ) ); 195 | 196 | cp.SetTitle( g_cmn.account[cp.param['account_id']].screen_name + ' ' + i18nGetMessage( 'i18n_0207' ), false ); 197 | 198 | //////////////////////////////////////// 199 | // 更新ボタンクリック 200 | //////////////////////////////////////// 201 | cont.find( '.panel_btns' ).find( '.saved_search_reload' ).click( function( e ) { 202 | // disabledなら処理しない 203 | if ( $( this ).hasClass( 'disabled' ) ) 204 | { 205 | return; 206 | } 207 | 208 | ListMake(); 209 | } ); 210 | 211 | // リスト部作成処理 212 | ListMake(); 213 | }; 214 | 215 | //////////////////////////////////////////////////////////// 216 | // 終了処理 217 | //////////////////////////////////////////////////////////// 218 | this.stop = function() { 219 | }; 220 | } 221 | -------------------------------------------------------------------------------- /js/lib/sha1.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined 3 | * in FIPS PUB 180-1 4 | * Version 2.1a Copyright Paul Johnston 2000 - 2002. 5 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 6 | * Distributed under the BSD License 7 | * See http://pajhome.org.uk/crypt/md5 for details. 8 | */ 9 | 10 | /* 11 | * Configurable variables. You may need to tweak these to be compatible with 12 | * the server-side, but the defaults work in most cases. 13 | */ 14 | var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ 15 | var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ 16 | var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ 17 | 18 | /* 19 | * These are the functions you'll usually want to call 20 | * They take string arguments and return either hex or base-64 encoded strings 21 | */ 22 | function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} 23 | function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} 24 | function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} 25 | function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} 26 | function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} 27 | function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} 28 | 29 | /* 30 | * Perform a simple self-test to see if the VM is working 31 | */ 32 | function sha1_vm_test() 33 | { 34 | return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; 35 | } 36 | 37 | /* 38 | * Calculate the SHA-1 of an array of big-endian words, and a bit length 39 | */ 40 | function core_sha1(x, len) 41 | { 42 | /* append padding */ 43 | x[len >> 5] |= 0x80 << (24 - len % 32); 44 | x[((len + 64 >> 9) << 4) + 15] = len; 45 | 46 | var w = Array(80); 47 | var a = 1732584193; 48 | var b = -271733879; 49 | var c = -1732584194; 50 | var d = 271733878; 51 | var e = -1009589776; 52 | 53 | for(var i = 0; i < x.length; i += 16) 54 | { 55 | var olda = a; 56 | var oldb = b; 57 | var oldc = c; 58 | var oldd = d; 59 | var olde = e; 60 | 61 | for(var j = 0; j < 80; j++) 62 | { 63 | if(j < 16) w[j] = x[i + j]; 64 | else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); 65 | var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), 66 | safe_add(safe_add(e, w[j]), sha1_kt(j))); 67 | e = d; 68 | d = c; 69 | c = rol(b, 30); 70 | b = a; 71 | a = t; 72 | } 73 | 74 | a = safe_add(a, olda); 75 | b = safe_add(b, oldb); 76 | c = safe_add(c, oldc); 77 | d = safe_add(d, oldd); 78 | e = safe_add(e, olde); 79 | } 80 | return Array(a, b, c, d, e); 81 | 82 | } 83 | 84 | /* 85 | * Perform the appropriate triplet combination function for the current 86 | * iteration 87 | */ 88 | function sha1_ft(t, b, c, d) 89 | { 90 | if(t < 20) return (b & c) | ((~b) & d); 91 | if(t < 40) return b ^ c ^ d; 92 | if(t < 60) return (b & c) | (b & d) | (c & d); 93 | return b ^ c ^ d; 94 | } 95 | 96 | /* 97 | * Determine the appropriate additive constant for the current iteration 98 | */ 99 | function sha1_kt(t) 100 | { 101 | return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : 102 | (t < 60) ? -1894007588 : -899497514; 103 | } 104 | 105 | /* 106 | * Calculate the HMAC-SHA1 of a key and some data 107 | */ 108 | function core_hmac_sha1(key, data) 109 | { 110 | var bkey = str2binb(key); 111 | if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); 112 | 113 | var ipad = Array(16), opad = Array(16); 114 | for(var i = 0; i < 16; i++) 115 | { 116 | ipad[i] = bkey[i] ^ 0x36363636; 117 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 118 | } 119 | 120 | var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); 121 | return core_sha1(opad.concat(hash), 512 + 160); 122 | } 123 | 124 | /* 125 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 126 | * to work around bugs in some JS interpreters. 127 | */ 128 | function safe_add(x, y) 129 | { 130 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 131 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 132 | return (msw << 16) | (lsw & 0xFFFF); 133 | } 134 | 135 | /* 136 | * Bitwise rotate a 32-bit number to the left. 137 | */ 138 | function rol(num, cnt) 139 | { 140 | return (num << cnt) | (num >>> (32 - cnt)); 141 | } 142 | 143 | /* 144 | * Convert an 8-bit or 16-bit string to an array of big-endian words 145 | * In 8-bit function, characters >255 have their hi-byte silently ignored. 146 | */ 147 | function str2binb(str) 148 | { 149 | var bin = Array(); 150 | var mask = (1 << chrsz) - 1; 151 | for(var i = 0; i < str.length * chrsz; i += chrsz) 152 | bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); 153 | return bin; 154 | } 155 | 156 | /* 157 | * Convert an array of big-endian words to a string 158 | */ 159 | function binb2str(bin) 160 | { 161 | var str = ""; 162 | var mask = (1 << chrsz) - 1; 163 | for(var i = 0; i < bin.length * 32; i += chrsz) 164 | str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); 165 | return str; 166 | } 167 | 168 | /* 169 | * Convert an array of big-endian words to a hex string. 170 | */ 171 | function binb2hex(binarray) 172 | { 173 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 174 | var str = ""; 175 | for(var i = 0; i < binarray.length * 4; i++) 176 | { 177 | str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + 178 | hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); 179 | } 180 | return str; 181 | } 182 | 183 | /* 184 | * Convert an array of big-endian words to a base-64 string 185 | */ 186 | function binb2b64(binarray) 187 | { 188 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 189 | var str = ""; 190 | for(var i = 0; i < binarray.length * 4; i += 3) 191 | { 192 | var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) 193 | | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) 194 | | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); 195 | for(var j = 0; j < 4; j++) 196 | { 197 | if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; 198 | else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); 199 | } 200 | } 201 | return str; 202 | } 203 | -------------------------------------------------------------------------------- /js/contents/impexp.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // インポート/エクスポート 3 | //////////////////////////////////////////////////////////////////////////////// 4 | Contents.impexp = function( cp ) 5 | { 6 | var p = $( '#' + cp.id ); 7 | var cont = p.find( 'div.contents' ); 8 | var filesystem; 9 | var exportfile = 'kurotwi.data.txt'; 10 | 11 | if ( window.webkitRequestFileSystem ) 12 | { 13 | webkitRequestFileSystem( TEMPORARY, 1024*1024*1, function( fs ) { 14 | filesystem = fs; 15 | } ); 16 | } 17 | 18 | cp.SetIcon( 'icon-folder-open' ); 19 | 20 | //////////////////////////////////////////////////////////// 21 | // 一時ファイル削除 22 | //////////////////////////////////////////////////////////// 23 | function DeleteTMPFile( name, callback, stopflg ) 24 | { 25 | if ( filesystem ) 26 | { 27 | filesystem.root.getFile( name, {}, function( entry ) { 28 | entry.remove( callback, function( e ) { 29 | console.log( 'remove' ); 30 | console.log( e ); 31 | if ( !stopflg ) 32 | { 33 | MessageBox( i18nGetMessage( 'i18n_0347' ) ); 34 | } 35 | } ); 36 | }, function( e ) { 37 | if ( e.name != 'NotFoundError' ) 38 | { 39 | console.log( 'getFile' ); 40 | console.log( e ); 41 | 42 | if ( !stopflg ) 43 | { 44 | MessageBox( i18nGetMessage( 'i18n_0347' ) ); 45 | } 46 | } 47 | else 48 | { 49 | callback(); 50 | } 51 | } ); 52 | } 53 | } 54 | 55 | //////////////////////////////////////////////////////////// 56 | // 開始処理 57 | //////////////////////////////////////////////////////////// 58 | this.start = function() { 59 | cont.addClass( 'impexp' ) 60 | .html( OutputTPL( 'impexp', {} ) ); 61 | 62 | cp.SetTitle( i18nGetMessage( 'i18n_0052' ) + '/' + i18nGetMessage( 'i18n_0053' ), false ); 63 | 64 | $( '#import .item .btn.exec' ).addClass( 'disabled' ); 65 | 66 | if ( !window.webkitRequestFileSystem ) 67 | { 68 | MessageBox( 'Chrome only' ); 69 | p.find( '.close' ).trigger( 'click', [false] ); 70 | return false; 71 | } 72 | 73 | //////////////////////////////////////// 74 | // リサイズ処理 75 | //////////////////////////////////////// 76 | cont.bind( 'contents_resize', function() { 77 | } ); 78 | 79 | cont.trigger( 'contents_resize' ); 80 | 81 | //////////////////////////////////////// 82 | // インポート実行ボタンクリック処理 83 | //////////////////////////////////////// 84 | $( '#import .item .btn.exec' ).click( function( e ) { 85 | // disabedなら処理しない 86 | if ( $( this ).hasClass( 'disabled' ) ) 87 | { 88 | return; 89 | } 90 | 91 | var file = $( '#importfile_input' )[0].files[0]; 92 | 93 | if ( file.type != 'text/plain' ) 94 | { 95 | MessageBox( i18nGetMessage( 'i18n_0348' ) ); 96 | return; 97 | } 98 | 99 | var reader = new FileReader(); 100 | 101 | reader.onload = ( function( thefile ) { 102 | return function( e ) { 103 | try { 104 | var _g_cmn = JSON.parse( decodeURIComponent_space( e.target.result ) ); 105 | } 106 | catch( e ) { 107 | console.log( e ); 108 | MessageBox( i18nGetMessage( 'i18n_0348' ) ); 109 | return; 110 | } 111 | 112 | if ( _g_cmn.current_version == undefined ) 113 | { 114 | MessageBox( i18nGetMessage( 'i18n_0348' ) ); 115 | return; 116 | } 117 | 118 | // バージョンアップと誤認しないようにバージョンを差し替え 119 | _g_cmn.current_version = g_cmn.current_version; 120 | 121 | try { 122 | var text = JSON.stringify( _g_cmn ); 123 | text = encodeURIComponent( text ); 124 | } 125 | catch( e ) { 126 | console.log( e ); 127 | MessageBox( i18nGetMessage( 'i18n_0348' ) ); 128 | return; 129 | } 130 | 131 | setUserInfo( 'g_cmn_V1', text ); 132 | g_saveend = false; 133 | chrome.tabs.reload(); 134 | }; 135 | } )( file ); 136 | 137 | reader.readAsText( file ); 138 | 139 | e.stopPropagation(); 140 | } ); 141 | 142 | //////////////////////////////////////// 143 | // エクスポート実行ボタンクリック処理 144 | //////////////////////////////////////// 145 | $( '#export .item .btn.exec' ).click( function( e ) { 146 | // disabedなら処理しない 147 | if ( $( this ).hasClass( 'disabled' ) ) 148 | { 149 | return; 150 | } 151 | 152 | var CreateNewFile = function() { 153 | filesystem.root.getFile( exportfile, { 'create': true }, function( entry ) { 154 | entry.createWriter( function( writer ) { 155 | writer.onwriteend = function() { 156 | $( '' )[0].click(); 157 | }; 158 | 159 | var lines = SaveDataText(); 160 | 161 | var blob = new Blob( [ lines ], { type: 'text.plain' } ); 162 | 163 | writer.write( blob ); 164 | }, function( e ) { 165 | console.log( 'createWriter' ); 166 | console.log( e ); 167 | MessageBox( i18nGetMessage( 'i18n_0347' ) ); 168 | } ); 169 | }, function( e ) { 170 | console.log( 'getFile' ); 171 | console.log( e ); 172 | MessageBox( i18nGetMessage( 'i18n_0347' ) ); 173 | } ); 174 | }; 175 | 176 | DeleteTMPFile( exportfile, CreateNewFile ); 177 | 178 | e.stopPropagation(); 179 | } ); 180 | 181 | //////////////////////////////////////// 182 | // ファイル選択ボタンクリック処理 183 | //////////////////////////////////////// 184 | $( '#importselectbtn' ).click( function( e ) { 185 | // disabledなら処理しない 186 | if ( $( this ).hasClass( 'disabled' ) ) 187 | { 188 | return; 189 | } 190 | 191 | $( '#importfile_input' ).click(); 192 | e.stopPropagation(); 193 | } ); 194 | 195 | //////////////////////////////////////// 196 | // ファイル選択変更時の処理 197 | //////////////////////////////////////// 198 | $( '#importfile_input' ).change( function( e ) { 199 | if ( $( '#importfile_input' )[0].files.length == 1 ) 200 | { 201 | $( '#import .item .btn.exec' ).removeClass( 'disabled' ); 202 | $( '#importfile' ).html( $( '#importfile_input' )[0].files[0].name ); 203 | } 204 | else 205 | { 206 | $( '#import .item .btn.exec' ).addClass( 'disabled' ); 207 | $( '#importfile' ).html( i18nGetMessage( 'i18n_0119' ) ); 208 | } 209 | 210 | e.stopPropagation(); 211 | } ); 212 | }; 213 | 214 | //////////////////////////////////////////////////////////// 215 | // 終了処理 216 | //////////////////////////////////////////////////////////// 217 | this.stop = function() { 218 | DeleteTMPFile( exportfile, function() {}, true ); 219 | }; 220 | } 221 | -------------------------------------------------------------------------------- /js/contents/dmbox.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // DM 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.dmbox = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | 11 | cp.SetIcon( 'icon-envelop' ); 12 | 13 | //////////////////////////////////////////////////////////// 14 | // 開始処理 15 | //////////////////////////////////////////////////////////// 16 | this.start = function() { 17 | cp.param.maxlen = 10000; 18 | 19 | cont.addClass( 'dmbox' ) 20 | .html( OutputTPL( 'dmbox', { maxlen: cp.param['maxlen'] } ) ); 21 | 22 | $( '#dmbox_cnt' ).hide(); 23 | 24 | cp.SetTitle( i18nGetMessage( 'i18n_0149', [cp.param.screen_name] ), false ); 25 | 26 | // 送信ボタンのツールチップを設定に合わせる 27 | var _tips = new Array( 'Ctrl+Enter', 'Shift+Enter', 'Enter' ); 28 | $( '#dmsend' ).attr( 'tooltip', i18nGetMessage( 'i18n_0250' ) + '(' + _tips[g_cmn.cmn_param.tweetkey] + ')' ); 29 | 30 | $( '#dmbox_text' ).focus(); 31 | 32 | //////////////////////////////////////// 33 | // リサイズ処理 34 | //////////////////////////////////////// 35 | cont.on( 'contents_resize', function() { 36 | $( '#dmbox_text' ).width( p.width() - 24 ); 37 | $( '#dmbox_box' ).find( 'div' ).first().width( p.width() - 12 ); 38 | 39 | var acc_h = cont.find( '.account_select' ).outerHeight(); 40 | 41 | var btn_h = $( '#dmbox_btn' ).parent().outerHeight(); 42 | 43 | $( '#dmbox_box' ).height( cont.outerHeight() - acc_h - 12 ); 44 | $( '#dmbox_text' ).height( $( '#dmbox_box' ).outerHeight() - btn_h - 24 ); 45 | } ); 46 | 47 | cont.trigger( 'contents_resize' ); 48 | 49 | //////////////////////////////////////// 50 | // アカウント情報更新 51 | //////////////////////////////////////// 52 | cont.on( 'account_update', function() { 53 | // アカウントが0件の場合はパネルを閉じる 54 | if ( AccountCount() == 0 ) 55 | { 56 | // ツイートパネルを閉じる 57 | p.find( '.close' ).trigger( 'click', [false] ); 58 | return; 59 | } 60 | else 61 | { 62 | AccountSelectMake( cp ); 63 | } 64 | } ); 65 | 66 | cont.trigger( 'account_update' ); 67 | 68 | //////////////////////////////////////// 69 | // 送信ボタンクリック処理 70 | //////////////////////////////////////// 71 | $( '#dmsend' ).click( function( e ) { 72 | // disabledなら処理しない 73 | if ( $( this ).hasClass( 'disabled' ) ) 74 | { 75 | return; 76 | } 77 | 78 | // 文字数チェック 79 | var val = dmbox_text.val(); 80 | var urls = twttr.txt.extractUrls( val ); 81 | 82 | for ( var i = 0, _len = urls.length ; i < _len ; i++ ) 83 | { 84 | val = val.replace( urls[i], tco ); 85 | } 86 | 87 | var slen = val.length; 88 | 89 | if ( slen > cp.param['maxlen'] ) 90 | { 91 | MessageBox( i18nGetMessage( 'i18n_0356', [slen, cp.param['maxlen']] ) ); 92 | return; 93 | } 94 | 95 | $( this ).addClass( 'disabled' ); 96 | 97 | var data = {}; 98 | var status = ''; 99 | 100 | status += $( '#dmbox_text' ).val(); 101 | 102 | var conf = confirm( i18nGetMessage( 'i18n_0150', [g_cmn.account[cp.param['account_id']]['screen_name'],cp.param['screen_name']] ) ); 103 | 104 | if ( !conf ) 105 | { 106 | $( this ).removeClass( 'disabled' ); 107 | e.stopPropagation(); 108 | return; 109 | } 110 | 111 | data['text'] = status; 112 | data['screen_name'] = cp.param['screen_name']; 113 | 114 | var param = { 115 | type: 'POST', 116 | url: ApiUrl( '1.1' ) + 'direct_messages/new.json', 117 | data: data, 118 | }; 119 | 120 | Blackout( true, false ); 121 | $( '#blackout' ).activity( { color: '#808080', width: 8, length: 14 } ); 122 | 123 | SendRequest( 124 | { 125 | action: 'oauth_send', 126 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 127 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 128 | param: param, 129 | id: cp.param['account_id'] 130 | }, 131 | function( res ) 132 | { 133 | if ( res.status == 200 ) 134 | { 135 | // テキストボックスを空にする 136 | $( '#dmbox_text' ).val( '' ) 137 | .trigger( 'keyup' ); 138 | 139 | // ツイート数表示の更新 140 | StatusesCountUpdate( cp.param['account_id'], 1 ); 141 | } 142 | else 143 | { 144 | console.log( 'status[' + res.status + ']' ); 145 | 146 | $( this ).removeClass( 'disabled' ); 147 | 148 | ApiError( i18nGetMessage( 'i18n_0081' ), res ); 149 | } 150 | 151 | Blackout( false, false ); 152 | $( '#blackout' ).activity( false ); 153 | } 154 | ); 155 | 156 | e.stopPropagation(); 157 | } ); 158 | 159 | var dmbox_text = $( '#dmbox_text' ); 160 | var tco = new String( '_______________________________' ).slice( 0, 23 ); 161 | 162 | //////////////////////////////////////// 163 | // 入力文字数によるボタン制御 164 | //////////////////////////////////////// 165 | $( '#dmbox_text' ).on( 'keyup change', function( e ) { 166 | var val = dmbox_text.val(); 167 | 168 | var slen = val.length; 169 | 170 | var btn = $( '#dmsend' ); 171 | 172 | if ( slen > 0 && slen <= cp.param['maxlen'] ) 173 | { 174 | btn.removeClass( 'disabled' ); 175 | } 176 | else 177 | { 178 | btn.addClass( 'disabled' ); 179 | } 180 | } ); 181 | 182 | //////////////////////////////////////// 183 | // キーボードショートカット 184 | //////////////////////////////////////// 185 | $( '#dmbox_text' ).keydown( function( e ) { 186 | // Enterに設定されているときは、Ctrl+Enterで改行 187 | if ( g_cmn.cmn_param.tweetkey == 2 && ( e.keyCode == 13 && e.ctrlKey == true ) ) 188 | { 189 | var obj = $( this ).get( 0 ); 190 | var spos = obj.selectionStart; 191 | var epos = obj.selectionEnd; 192 | var s = obj.value; 193 | var np = spos + 1; 194 | obj.value = s.substr( 0, spos ) + '\n' + s.substr( epos ); 195 | obj.setSelectionRange( np, np ); 196 | return false; 197 | } 198 | 199 | if ( ( g_cmn.cmn_param.tweetkey == 0 && ( e.keyCode == 13 && e.ctrlKey == true ) ) || 200 | ( g_cmn.cmn_param.tweetkey == 1 && ( e.keyCode == 13 && e.shiftKey == true ) ) || 201 | ( g_cmn.cmn_param.tweetkey == 2 && ( e.keyCode == 13 && e.ctrlKey == false && e.shiftKey == false ) ) ) 202 | { 203 | $( '#dmsend' ).trigger( 'click' ); 204 | return false; 205 | } 206 | } ); 207 | 208 | // 旧DM廃止のため 209 | p.find( '.close' ).trigger( 'click', [false] ); 210 | }; 211 | 212 | //////////////////////////////////////////////////////////// 213 | // 終了処理 214 | //////////////////////////////////////////////////////////// 215 | this.stop = function() { 216 | }; 217 | } 218 | -------------------------------------------------------------------------------- /js/contents/api_remaining.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // API残数 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.api_remaining = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | var scrollPos = null; 11 | 12 | cp.SetIcon( 'icon-twitter' ); 13 | 14 | // API1.1対応済み 15 | var apis = {}; 16 | apis['/statuses/home_timeline'] = { title: i18nGetMessage( 'i18n_0152' ), prio: 0 }; 17 | apis['/statuses/mentions_timeline'] = { title: i18nGetMessage( 'i18n_0026' ), prio: 1 }; 18 | apis['/lists/statuses'] = { title: i18nGetMessage( 'i18n_0167' ), prio: 2 }; 19 | apis['/statuses/user_timeline'] = { title: i18nGetMessage( 'i18n_0291' ), prio: 3 }; 20 | apis['/direct_messages'] = { title: i18nGetMessage( 'i18n_0021' ), prio: 4 }; 21 | apis['/search/tweets'] = { title: i18nGetMessage( 'i18n_0206' ), prio: 5 }; 22 | apis['/users/show/:id'] = { title: i18nGetMessage( 'i18n_0292' ), prio: 6 }; 23 | apis['/statuses/show/:id'] = { title: i18nGetMessage( 'i18n_0293' ), prio: 7 }; 24 | apis['/users/search'] = { title: i18nGetMessage( 'i18n_0159' ), prio: 8 }; 25 | apis['/lists/list'] = { title: i18nGetMessage( 'i18n_0294' ), prio: 9 }; 26 | apis['/direct_messages/sent'] = { title: i18nGetMessage( 'i18n_0251' ), prio: 10 }; 27 | apis['/favorites/list'] = { title: i18nGetMessage( 'i18n_0054' ), prio: 11 }; 28 | apis['/trends/place'] = { title: i18nGetMessage( 'i18n_0095' ), prio: 12 }; 29 | apis['/trends/available'] = { title: i18nGetMessage( 'i18n_0295' ), prio: 13 }; 30 | apis['/saved_searches/list'] = { title: i18nGetMessage( 'i18n_0207' ), prio: 14 }; 31 | apis['/users/lookup'] = { title: i18nGetMessage( 'i18n_0316' ), prio: 15 }; 32 | apis['/application/rate_limit_status'] = { title: i18nGetMessage( 'i18n_0296' ), prio: 16 }; 33 | apis['/blocks/ids'] = { title: i18nGetMessage( 'i18n_0318' ), prio: 17 }; 34 | apis['/friends/ids'] = { title: i18nGetMessage( 'i18n_0319' ), prio: 18 }; 35 | apis['/followers/ids'] = { title: i18nGetMessage( 'i18n_0320' ), prio: 19 }; 36 | apis['/friendships/incoming'] = { title: i18nGetMessage( 'i18n_0321' ), prio: 20 }; 37 | apis['/friendships/no_retweets/ids'] = { title: i18nGetMessage( 'i18n_0326' ), prio: 21 }; 38 | apis['/mutes/users/ids'] = { title: i18nGetMessage( 'i18n_0367' ), prio: 22 }; 39 | apis['/help/configuration'] = { title: i18nGetMessage( 'i18n_0297' ), prio: 23 }; 40 | 41 | var apis_length = 0; 42 | 43 | for ( var api in apis ) 44 | { 45 | apis_length++; 46 | } 47 | 48 | //////////////////////////////////////////////////////////// 49 | // リスト部作成 50 | //////////////////////////////////////////////////////////// 51 | var ListMake = function() { 52 | var account = g_cmn.account[cp.param['account_id']]; 53 | var param = { 54 | type: 'GET', 55 | url: ApiUrl( '1.1' ) + 'application/rate_limit_status.json', 56 | data: { 57 | resources: 'account,application,blocks,direct_messages,favorites,followers,friends,friendships,geo,help,lists,saved_searches,search,statuses,trends,users,friends,followers,mutes', 58 | }, 59 | }; 60 | 61 | cont.activity( { color: '#ffffff' } ); 62 | 63 | SendRequest( 64 | { 65 | action: 'oauth_send', 66 | acsToken: account.accessToken, 67 | acsSecret: account.accessSecret, 68 | param: param, 69 | id: cp.param['account_id'] 70 | }, 71 | function( res ) 72 | { 73 | var items = new Array( apis_length ); 74 | var dt; 75 | 76 | if ( res.status == 200 ) 77 | { 78 | for ( var resource in res.json.resources ) 79 | { 80 | for ( var api in res.json.resources[resource] ) 81 | { 82 | if ( apis[api] != undefined ) 83 | { 84 | dt = new Date(); 85 | dt.setTime( res.json.resources[resource][api]['reset'] * 1000 ); 86 | 87 | items[apis[api].prio] = { 88 | api: api, 89 | title: apis[api].title, 90 | remaining: res.json.resources[resource][api]['remaining'], 91 | limit: res.json.resources[resource][api]['limit'], 92 | reset: ( '00' + dt.getHours() ).slice( -2 ) + ':' + 93 | ( '00' + dt.getMinutes() ).slice( -2 ) + ':' + 94 | ( '00' + dt.getSeconds() ).slice( -2 ), 95 | per: Math.floor( res.json.resources[resource][api]['remaining'] / res.json.resources[resource][api]['limit'] * 100 ), 96 | reltime: DateConv( dt.toGMTString().replace( 'GMT', '+0000' ), 2 ) 97 | }; 98 | } 99 | } 100 | } 101 | 102 | cont.find( '.api_remaining_list' ).html( OutputTPL( 'api_remaining_list', { items: items } ) ); 103 | 104 | for ( var i = 0, item, n = 0, _len = items.length ; i < _len ; i++ ) 105 | { 106 | if ( items[i] == undefined ) 107 | { 108 | continue; 109 | } 110 | 111 | item = cont.find( '.api_remaining_list' ).find( '.item:eq(' + n + ')' ); 112 | n++; 113 | 114 | item.find( '.used' ).css( { 115 | width: 100 - items[i].per + '%', 116 | left: items[i].per + '%', 117 | } ); 118 | } 119 | 120 | cont.trigger( 'contents_resize' ).activity( false ); 121 | } 122 | else 123 | { 124 | ApiError( i18nGetMessage( 'i18n_0298' ), res ); 125 | cont.activity( false ); 126 | } 127 | } 128 | ); 129 | }; 130 | 131 | //////////////////////////////////////////////////////////// 132 | // 開始処理 133 | //////////////////////////////////////////////////////////// 134 | this.start = function() { 135 | //////////////////////////////////////// 136 | // 最小化/設定切替時のスクロール位置 137 | // 保存/復元 138 | //////////////////////////////////////// 139 | cont.on( 'contents_scrollsave', function( e, type ) { 140 | // 保存 141 | if ( type == 0 ) 142 | { 143 | if ( scrollPos == null ) 144 | { 145 | scrollPos = cont.find( '.api_remaining_list' ).scrollTop(); 146 | } 147 | } 148 | // 復元 149 | else 150 | { 151 | if ( scrollPos != null ) 152 | { 153 | cont.find( '.api_remaining_list' ).scrollTop( scrollPos ); 154 | scrollPos = null; 155 | } 156 | } 157 | } ); 158 | 159 | //////////////////////////////////////// 160 | // リサイズ処理 161 | //////////////////////////////////////// 162 | cont.on( 'contents_resize', function() { 163 | cont.find( '.api_remaining_list' ).height( cont.height() - cont.find( '.panel_btns' ).height() - 1 ); 164 | } ); 165 | 166 | //////////////////////////////////////// 167 | // このパネルを開いたアカウントが 168 | // 削除された場合 169 | //////////////////////////////////////// 170 | var AccountAliveCheck = function() { 171 | if ( g_cmn.account[cp.param['account_id']] == undefined ) 172 | { 173 | // パネルを閉じる 174 | p.find( '.close' ).trigger( 'click', [false] ); 175 | return false; 176 | } 177 | 178 | return true; 179 | }; 180 | 181 | //////////////////////////////////////// 182 | // アカウント変更 183 | //////////////////////////////////////// 184 | cont.on( 'account_change', function( e, account_id ) { 185 | if ( cp.param['account_id'] == account_id ) 186 | { 187 | } 188 | else 189 | { 190 | p.find( 'div.titlebar' ).find( '.titlename' ).text( g_cmn.account[account_id].screen_name ); 191 | cp.param['account_id'] = account_id; 192 | 193 | cp.title = cp.title.replace( /().*(<\/span>)/, 194 | '$1' + g_cmn.account[account_id].screen_name + '$2' ); 195 | 196 | // パネルリストの更新" 197 | $( document ).trigger( 'panellist_changed' ); 198 | 199 | // 更新 200 | ListMake(); 201 | } 202 | } ); 203 | 204 | //////////////////////////////////////// 205 | // アカウント情報更新 206 | //////////////////////////////////////// 207 | cont.on( 'account_update', function() { 208 | AccountAliveCheck(); 209 | 210 | // アカウント選択リスト更新 211 | var s = ''; 212 | var id; 213 | 214 | for ( var i = 0, _len = g_cmn.account_order.length ; i < _len ; i++ ) 215 | { 216 | id = g_cmn.account_order[i]; 217 | s += '' + g_cmn.account[id].screen_name + ''; 218 | } 219 | 220 | p.find( 'div.titlebar' ).find( '.titlename_list' ).html( s ) 221 | .find( 'span' ).click( function( e ) { 222 | p.find( 'div.contents' ).trigger( 'account_change', [$( this ).attr( 'account_id' )] ); 223 | $( this ).parent().hide(); 224 | } ); 225 | } ); 226 | 227 | if ( !AccountAliveCheck() ) 228 | { 229 | return; 230 | } 231 | 232 | //////////////////////////////////////// 233 | // API残数変更 234 | //////////////////////////////////////// 235 | cont.on( 'api_remaining_update', function( e, id ) { 236 | if ( id == cp.param['account_id'] ) 237 | { 238 | ListMake(); 239 | } 240 | } ); 241 | 242 | // 全体を作成 243 | cont.addClass( 'api_remaining' ) 244 | .html( OutputTPL( 'api_remaining', {} ) ); 245 | 246 | cp.SetTitle( i18nGetMessage( 'i18n_0296' ) + ' (' + g_cmn.account[cp.param['account_id']].screen_name + ')', false ); 247 | 248 | //////////////////////////////////////// 249 | // 更新ボタンクリック 250 | //////////////////////////////////////// 251 | cont.find( '.panel_btns' ).find( '.api_remaining_reload' ).click( function( e ) { 252 | // disabledなら処理しない 253 | if ( $( this ).hasClass( 'disabled' ) ) 254 | { 255 | return; 256 | } 257 | 258 | ListMake(); 259 | 260 | e.stopPropagation(); 261 | } ); 262 | 263 | // リスト部作成処理 264 | ListMake(); 265 | }; 266 | 267 | //////////////////////////////////////////////////////////// 268 | // 終了処理 269 | //////////////////////////////////////////////////////////// 270 | this.stop = function() { 271 | }; 272 | } 273 | -------------------------------------------------------------------------------- /js/contents/image.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // イメージ表示 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.image = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | var scaleX = 1, scaleY = 1, rotate = 0; 11 | var fit = true; 12 | 13 | cp.SetIcon( 'icon-image' ); 14 | 15 | //////////////////////////////////////////////////////////// 16 | // タイトル設定 17 | //////////////////////////////////////////////////////////// 18 | const setTitle = ( append ) => { 19 | let title_url = ( cp.param['video'] && Array.isArray( cp.param['url'] ) ) ? cp.param['url'][0] : cp.param['url'] 20 | title_url = title_url.replace( /api_key=\w+\&/, '' ) 21 | 22 | if ( title_url.match( /^data:image\// ) ) 23 | { 24 | title_url = i18nGetMessage( 'i18n_0256' ) 25 | } 26 | 27 | cp.SetTitle( i18nGetMessage( 'i18n_0199' ) + ' - ' + title_url + append, false ) 28 | } 29 | 30 | //////////////////////////////////////////////////////////// 31 | // 開始処理 32 | //////////////////////////////////////////////////////////// 33 | this.start = function() { 34 | setTitle() 35 | setTimeout( function() { cont.activity( { color: '#ffffff' } ); }, 0 ); 36 | 37 | if ( cp.param['video'] ) 38 | { 39 | let items = [] 40 | 41 | if ( Array.isArray( cp.param['url'] ) ) { 42 | for ( let i = 0 ; i < cp.param['url'].length ; i++ ) { 43 | items.push( { 44 | url: cp.param['url'][i], 45 | contenttype: cp.param['contenttype'][i] 46 | } ) 47 | } 48 | } else { 49 | items.push( { 50 | url: cp.param['url'], 51 | contenttype: cp.param['contenttype'] 52 | } ) 53 | } 54 | 55 | cont.addClass( 'image' ) 56 | .html( OutputTPL( 'image', { items: items, video: true, poster: cp.param['poster'] } ) ); 57 | } 58 | else 59 | { 60 | cont.addClass( 'image' ) 61 | .html( OutputTPL( 'image', { url: cp.param['url'] } ) ); 62 | } 63 | 64 | cont.find( '.resizebtn' ).hide(); 65 | 66 | //////////////////////////////////////// 67 | // 画像のサイズをパネルに合わせる 68 | //////////////////////////////////////// 69 | var FitPanelSize = function() { 70 | var pw = cont.outerWidth(); 71 | var ph = cont.outerHeight() - p.find( 'div.titlebar' ).outerHeight()+5; 72 | 73 | var nw, nh; 74 | 75 | if ( cp.param['video'] ) 76 | { 77 | if ( cont.find( 'video' ).length ) { 78 | nw = cont.find( 'video' ).get( 0 ).videoWidth; 79 | nh = cont.find( 'video' ).get( 0 ).videoHeight; 80 | } 81 | } 82 | else 83 | { 84 | nw = cont.find( 'img.image' ).get( 0 ).naturalWidth; 85 | nh = cont.find( 'img.image' ).get( 0 ).naturalHeight; 86 | } 87 | 88 | var pnw = pw; 89 | var pnh = pw / nw * nh; 90 | 91 | if ( pnh > ph ) 92 | { 93 | pnh = ph; 94 | pnw = ph / nh * nw; 95 | } 96 | 97 | cont.find( 'img.image, video' ).css( { 98 | width: pnw, 99 | height: pnh, 100 | } ); 101 | }; 102 | 103 | //////////////////////////////////////// 104 | // 画像のサイズを実サイズにする 105 | //////////////////////////////////////// 106 | var RealSize = function() { 107 | if ( cp.param['video'] ) 108 | { 109 | var img = cont.find( 'video' ); 110 | 111 | img.width( img.get( 0 ).videoWidth ) 112 | .height( img.get( 0 ).videoHeight ); 113 | } 114 | else 115 | { 116 | var img = cont.find( 'img.image' ); 117 | 118 | img.width( img.get( 0 ).naturalWidth ) 119 | .height( img.get( 0 ).naturalHeight ); 120 | } 121 | }; 122 | 123 | //////////////////////////////////////// 124 | // ロード完了 125 | //////////////////////////////////////// 126 | var LoadedEvent = function() { 127 | // 実サイズ 128 | var nw, nh; 129 | 130 | if ( cp.param['video'] ) 131 | { 132 | nw = $( this ).get( 0 ).videoWidth; 133 | nh = $( this ).get( 0 ).videoHeight; 134 | setTitle( ' (' + nw + '×' + nh + ')') 135 | } 136 | else 137 | { 138 | nw = $( this ).get( 0 ).naturalWidth; 139 | nh = $( this ).get( 0 ).naturalHeight; 140 | setTitle( ' (' + nw + '×' + nh + ')' ) 141 | } 142 | 143 | setTimeout( function() {cont.activity( false ); }, 0 ); 144 | 145 | // 巨大画像の表示抑止 146 | var mainw = $( window ).width() * 0.95; 147 | var mainh = ( $( window ).height() ) * 0.85; 148 | 149 | if ( nw > mainw ) 150 | { 151 | nh = mainw * nh / nw; 152 | nw = mainw; 153 | } 154 | 155 | if ( nh > mainh ) 156 | { 157 | nw = mainh * nw / nh; 158 | nh = mainh; 159 | } 160 | 161 | // タイトルバーのボタン表示分の幅を確保 162 | var barsize = p.find( 'div.titlebar' ).find( '.close' ).outerWidth() * 3 + 48; 163 | 164 | nw = ( nw < barsize ) ? barsize : nw; 165 | 166 | if ( nh < 200 ) 167 | { 168 | nh = 200; 169 | } 170 | 171 | nh = nh + p.find( 'div.titlebar' ).outerHeight() + 24; 172 | 173 | p.css( { width: nw, height: nh, left: ( $( 'body' ).outerWidth() - nw ) / 2 + $( document ).scrollLeft() } ) 174 | .trigger( 'resize' ); 175 | 176 | // 画像ダブルクリックで閉じる 177 | cont.find( 'img.image,video' ).on( 'dblclick', function( e ) { 178 | p.find( '.close' ).trigger( 'click', [false] ); 179 | } ); 180 | 181 | //////////////////////////////////////// 182 | // パネルサイズに合わせる 183 | //////////////////////////////////////// 184 | cont.find( '.img_panelsize' ).click( function( e ) { 185 | fit = true; 186 | 187 | FitPanelSize(); 188 | 189 | p.trigger( 'resize' ); 190 | e.stopPropagation(); 191 | } ); 192 | 193 | //////////////////////////////////////// 194 | // 実サイズで表示 195 | //////////////////////////////////////// 196 | cont.find( '.img_fullsize' ).click( function( e ) { 197 | fit = false; 198 | 199 | RealSize(); 200 | 201 | p.trigger( 'resize' ); 202 | e.stopPropagation(); 203 | } ); 204 | 205 | //////////////////////////////////////// 206 | // 上下反転 207 | //////////////////////////////////////// 208 | cont.find( '.img_udreverse' ).click( function( e ) { 209 | scaleY = ( scaleY == 1 ) ? -1 : 1; 210 | 211 | cont.find( 'img.image, video' ).css( { '-webkit-transform': 'scale(' + scaleX + ',' + scaleY + ') rotate(' + rotate + 'deg)' } ); 212 | e.stopPropagation(); 213 | } ); 214 | 215 | //////////////////////////////////////// 216 | // 左右反転 217 | //////////////////////////////////////// 218 | cont.find( '.img_lrreverse' ).click( function( e ) { 219 | scaleX = ( scaleX == 1 ) ? -1 : 1; 220 | 221 | cont.find( 'img.image, video' ).css( { '-webkit-transform': 'scale(' + scaleX + ',' + scaleY + ') rotate(' + rotate + 'deg)' } ); 222 | e.stopPropagation(); 223 | } ); 224 | 225 | //////////////////////////////////////// 226 | // 回転 227 | //////////////////////////////////////// 228 | cont.find( '.img_rotate' ).click( function( e ) { 229 | rotate = ( rotate == 270 ) ? 0 : rotate + 90; 230 | 231 | cont.find( 'img.image, video' ).css( { '-webkit-transform': 'scale(' + scaleX + ',' + scaleY + ') rotate(' + rotate + 'deg)' } ); 232 | e.stopPropagation(); 233 | } ); 234 | 235 | //////////////////////////////////////// 236 | // リサイズボタン群表示 237 | //////////////////////////////////////// 238 | if ( !cp.param['video'] ) 239 | { 240 | cont.mouseenter( function( e ) { 241 | cont.find( '.resizebtn' ).show(); 242 | } ); 243 | } 244 | 245 | //////////////////////////////////////// 246 | // リサイズボタン群非表示 247 | //////////////////////////////////////// 248 | cont.mouseleave( function( e ) { 249 | cont.find( '.resizebtn' ).hide(); 250 | } ); 251 | 252 | //////////////////////////////////////// 253 | // 音量 254 | //////////////////////////////////////// 255 | if ( cp.param['video'] ) { 256 | cont.find( 'video' ) 257 | .prop( 'volume', g_cmn.video_volume ) 258 | .on( 'volumechange', function() { 259 | g_cmn.video_volume = this.volume 260 | } ) 261 | } 262 | 263 | // 初期表示 264 | cont.find( '.img_panelsize' ).trigger( 'click' ); 265 | }; 266 | 267 | cont.find( 'img.image' ).on( 'load', LoadedEvent ); 268 | cont.find( 'video' ).on( 'loadedmetadata', LoadedEvent ); 269 | 270 | if ( g_devmode ) { 271 | console.log( '--event-----------' ) 272 | cont.find( 'video' ).on( 'loadstart', () => { console.log('loadstart') } ) 273 | cont.find( 'video' ).on( 'suspend', () => { console.log('suspend') } ) 274 | cont.find( 'video' ).on( 'abort', () => { console.log('abort') } ) 275 | cont.find( 'video' ).on( 'error', () => { console.log('error') } ) 276 | cont.find( 'video' ).on( 'emptied', () => { console.log('emptied') } ) 277 | cont.find( 'video' ).on( 'stalled', () => { console.log('stalled') } ) 278 | cont.find( 'video' ).on( 'loadedmetadata', () => { console.log('loadedmetadata') } ) 279 | cont.find( 'video' ).on( 'canplay', () => { console.log('canplay') } ) 280 | cont.find( 'video' ).on( 'playing', () => { console.log('playing') } ) 281 | } 282 | 283 | //////////////////////////////////////// 284 | // 読み込み失敗 285 | //////////////////////////////////////// 286 | var ErrorEvent = function( e ) { 287 | if ( g_devmode ) { 288 | console.log( '読み込み失敗' ) 289 | console.log( cont.find( 'video' ).get(0).error ) 290 | } 291 | 292 | setTitle( ' (' + i18nGetMessage( 'i18n_0258' ) + ')' ) 293 | setTimeout( function() { cont.activity( false ); }, 0 ); 294 | 295 | cont.find( 'video' ).addClass( 'error' ) 296 | //cont.find( 'video' ).remove() 297 | }; 298 | 299 | cont.find( 'img.image,video' ).on( 'error', ErrorEvent ); 300 | 301 | //////////////////////////////////////// 302 | // リサイズ処理 303 | //////////////////////////////////////// 304 | cont.on( 'contents_resize', function() { 305 | if ( fit ) 306 | { 307 | FitPanelSize(); 308 | } 309 | } ); 310 | }; 311 | 312 | //////////////////////////////////////////////////////////// 313 | // 終了処理 314 | //////////////////////////////////////////////////////////// 315 | this.stop = function() { 316 | }; 317 | } 318 | -------------------------------------------------------------------------------- /js/contents/accountset.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // アカウント設定 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.accountset = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | 11 | cp.SetIcon( 'icon-user' ); 12 | 13 | var SetTitle = function() { 14 | cp.SetTitle( i18nGetMessage( 'i18n_0047' ) + '(' + g_cmn.account[cp.param.account_id].screen_name + ')', false ); 15 | 16 | } 17 | 18 | //////////////////////////////////////////////////////////// 19 | // 初期入力値設定 20 | //////////////////////////////////////////////////////////// 21 | var MakeInput = function() { 22 | cont.html( '' ) 23 | .addClass( 'accountset' ); 24 | 25 | cont.activity( { color: '#ffffff' } ); 26 | 27 | var param = { 28 | type: 'GET', 29 | url: ApiUrl( '1.1' ) + 'users/show.json', 30 | data: { 31 | user_id: g_cmn.account[cp.param['account_id']].user_id, 32 | }, 33 | }; 34 | 35 | SendRequest( 36 | { 37 | action: 'oauth_send', 38 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 39 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 40 | param: param, 41 | id:cp.param['account_id'] 42 | }, 43 | function( res ) 44 | { 45 | if ( res.status == 200 ) 46 | { 47 | cont.html( OutputTPL( 'accountset', { 48 | icon: res.json.profile_image_url_https, 49 | name: escapeHTML( res.json.name ), 50 | url: escapeHTML( res.json.url ), 51 | location: escapeHTML( res.json.location ), 52 | desc: escapeHTML( res.json.description ), 53 | } ) ); 54 | 55 | $( '#iconselectbtn' ).removeClass( 'disabled' ); 56 | $( '#iconuploadbtn' ).addClass( 'disabled' ); 57 | $( '#profupdatebtn' ).removeClass( 'disabled' ); 58 | } 59 | else 60 | { 61 | ApiError( i18nGetMessage( 'i18n_0160' ), res ); 62 | 63 | cont.html( OutputTPL( 'accountset', { 64 | icon: '', 65 | name: '', 66 | url: '', 67 | location: '', 68 | desc: '', 69 | } ) ); 70 | 71 | $( '#iconselectbtn' ).addClass( 'disabled' ); 72 | $( '#iconuploadbtn' ).addClass( 'disabled' ); 73 | $( '#profupdatebtn' ).addClass( 'disabled' ); 74 | } 75 | 76 | $( 'panel' ).find( 'div.contents' ).trigger( 'api_remaining_update', [cp.param['account_id']] ); 77 | 78 | g_cmn.account[cp.param['account_id']].icon = res.json.profile_image_url_https; 79 | $( '#head' ).trigger( 'account_update' ); 80 | 81 | $( '#profname' ).focus(); 82 | 83 | SetFont( true ); 84 | cont.activity( false ); 85 | 86 | //////////////////////////////////////// 87 | // ファイル選択ボタンクリック処理 88 | //////////////////////////////////////// 89 | $( '#iconselectbtn' ).click( function( e ) { 90 | // disabledなら処理しない 91 | if ( $( this ).hasClass( 'disabled' ) ) 92 | { 93 | return; 94 | } 95 | 96 | $( '#iconupload_input' ).click(); 97 | e.stopPropagation(); 98 | } ); 99 | 100 | //////////////////////////////////////// 101 | // ファイル選択変更時の処理 102 | //////////////////////////////////////// 103 | $( '#iconupload_input' ).change( function( e ) { 104 | if ( $( '#iconupload_input' )[0].files.length == 1 ) 105 | { 106 | $( '#iconuploadbtn' ).removeClass( 'disabled' ); 107 | 108 | var f = $( '#iconupload_input' )[0].files[0]; 109 | 110 | $( '#iconuploadbox_select > span' ).html( f.name ); 111 | 112 | if ( f.type.match( 'image.*' ) ) 113 | { 114 | var reader = new FileReader(); 115 | 116 | reader.onload = function( e ) { 117 | var result = e.target.result; 118 | 119 | $( '#iconimg' ).attr( 'src', result ); 120 | }; 121 | 122 | reader.readAsDataURL( f ); 123 | } 124 | } 125 | else 126 | { 127 | $( '#iconuploadbtn' ).addClass( 'disabled' ); 128 | $( '#iconuploadbox_select > span' ).html( i18nGetMessage( 'i18n_0119' ) + '
' + i18nGetMessage( 'i18n_0019' ) + '' ); 129 | } 130 | 131 | e.stopPropagation(); 132 | } ); 133 | 134 | //////////////////////////////////////// 135 | // アイコン更新ボタンクリック処理 136 | //////////////////////////////////////// 137 | $( '#iconuploadbtn' ).click( function( e ) { 138 | // disabledなら処理しない 139 | if ( $( this ).hasClass( 'disabled' ) ) 140 | { 141 | return; 142 | } 143 | 144 | // バックグラウンドの変数にアップロードするファイルを設定 145 | uploadIconFile = $( '#iconupload_input' ).get( 0 ).files[0]; 146 | 147 | $( '#iconselectbtn' ).addClass( 'disabled' ); 148 | $( '#iconuploadbtn' ).addClass( 'disabled' ); 149 | 150 | Blackout( true ); 151 | $( '#blackout' ).activity( { color: '#808080', width: 8, length: 14 } ); 152 | 153 | SendRequest( 154 | { 155 | action: 'icon_upload', 156 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 157 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 158 | id: cp.param['account_id'], 159 | }, 160 | function( res ) 161 | { 162 | if ( res != '' ) 163 | { 164 | $( '#iconimg' ).parent().activity( { color: 'ffffff' } ); 165 | 166 | var before_url = $( '#iconimg' ).attr( 'src' ); 167 | var chkcnt = 0; 168 | 169 | // アイコンの変更反映チェック 170 | var IconUpdateCheck = function() { 171 | var param = { 172 | type: 'GET', 173 | url: ApiUrl( '1.1' ) + 'users/show.json', 174 | data: { 175 | user_id: g_cmn.account[cp.param['account_id']].user_id, 176 | }, 177 | }; 178 | 179 | SendRequest( 180 | { 181 | action: 'oauth_send', 182 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 183 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 184 | param: param, 185 | id:cp.param['account_id'] 186 | }, 187 | function( res ) 188 | { 189 | if ( res.status == 200 ) 190 | { 191 | if ( res.json.profile_image_url_https != before_url ) 192 | { 193 | $( '#iconimg' ).attr( 'src', res.json.profile_image_url_https ) 194 | .parent().activity( false ); 195 | 196 | g_cmn.account[cp.param['account_id']].icon = res.json.profile_image_url_https; 197 | $( '#head' ).trigger( 'account_update' ); 198 | 199 | for ( var i = 0, _len = g_cmn.toolbar_user.length ; i < _len ; i++ ) 200 | { 201 | if ( g_cmn.toolbar_user[i].user_id == g_cmn.account[cp.param['account_id']].user_id ) 202 | { 203 | g_cmn.toolbar_user[i].icon = res.json.profile_image_url_https; 204 | } 205 | } 206 | 207 | UpdateToolbarUser(); 208 | } 209 | else 210 | { 211 | chkcnt++; 212 | 213 | if ( chkcnt != 3 ) 214 | { 215 | setTimeout( IconUpdateCheck, 3000 ); 216 | } 217 | else 218 | { 219 | $( '#iconimg' ).parent().activity( false ); 220 | } 221 | } 222 | } 223 | else 224 | { 225 | $( '#iconimg' ).parent().activity( false ); 226 | } 227 | 228 | $( 'panel' ).find( 'div.contents' ).trigger( 'api_remaining_update', [cp.param['account_id']] ); 229 | } 230 | ); 231 | }; 232 | 233 | setTimeout( IconUpdateCheck, 5000 ); 234 | } 235 | else 236 | { 237 | MessageBox( i18nGetMessage( 'i18n_0118' ) ); 238 | } 239 | 240 | Blackout( false ); 241 | $( '#blackout' ).activity( false ); 242 | 243 | $( '#iconselectbtn' ).removeClass( 'disabled' ); 244 | $( '#iconuploadbtn' ).removeClass( 'disabled' ); 245 | } 246 | ); 247 | 248 | e.stopPropagation(); 249 | } ); 250 | 251 | //////////////////////////////////////// 252 | // プロフィール保存ボタンクリック処理 253 | //////////////////////////////////////// 254 | $( '#profupdatebtn' ).click( function( e ) { 255 | // disabledなら処理しない 256 | if ( $( this ).hasClass( 'disabled' ) ) 257 | { 258 | return; 259 | } 260 | 261 | var param = { 262 | type: 'POST', 263 | url: ApiUrl( '1.1' ) + 'account/update_profile.json', 264 | data: { 265 | name: $( '#profname' ).val(), 266 | url: $( '#profurl' ).val(), 267 | location: $( '#proflocation' ).val(), 268 | description: $( '#profdesc' ).val() 269 | } 270 | }; 271 | 272 | Blackout( true ); 273 | $( '#blackout' ).activity( { color: '#808080', width: 8, length: 14 } ); 274 | 275 | SendRequest( 276 | { 277 | action: 'oauth_send', 278 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 279 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 280 | param: param, 281 | id: cp.param['account_id'] 282 | }, 283 | function( res ) 284 | { 285 | if ( res.status == 200 ) 286 | { 287 | } 288 | else 289 | { 290 | console.log( 'status[' + res.status + ']' ); 291 | 292 | $( this ).removeClass( 'disabled' ); 293 | 294 | ApiError( i18nGetMessage( 'i18n_0147' ), res ); 295 | } 296 | 297 | Blackout( false ); 298 | $( '#blackout' ).activity( false ); 299 | } 300 | ); 301 | } ); 302 | } 303 | ); 304 | }; 305 | 306 | //////////////////////////////////////////////////////////// 307 | // 開始処理 308 | //////////////////////////////////////////////////////////// 309 | this.start = function() { 310 | //////////////////////////////////////// 311 | // このパネルを開いたアカウントが 312 | // 削除された場合 313 | //////////////////////////////////////// 314 | var AccountAliveCheck = function() { 315 | if ( g_cmn.account[cp.param['account_id']] == undefined ) 316 | { 317 | // パネルを閉じる 318 | p.find( '.close' ).trigger( 'click', [false] ); 319 | return false; 320 | } 321 | 322 | return true; 323 | }; 324 | 325 | //////////////////////////////////////// 326 | // アカウント情報更新 327 | //////////////////////////////////////// 328 | cont.on( 'account_update', function() { 329 | AccountAliveCheck(); 330 | } ); 331 | 332 | //////////////////////////////////////// 333 | // アカウント変更 334 | //////////////////////////////////////// 335 | cont.on( 'account_change', function() { 336 | SetTitle(); 337 | MakeInput(); 338 | } ); 339 | 340 | SetTitle(); 341 | 342 | // 全体を作成 343 | MakeInput(); 344 | }; 345 | 346 | //////////////////////////////////////////////////////////// 347 | // 終了処理 348 | //////////////////////////////////////////////////////////// 349 | this.stop = function() { 350 | }; 351 | } 352 | -------------------------------------------------------------------------------- /js/contents/usersearch.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // ユーザ検索一覧 5 | //////////////////////////////////////////////////////////////////////////////// 6 | Contents.usersearch = function( cp ) 7 | { 8 | var p = $( '#' + cp.id ); 9 | var cont = p.find( 'div.contents' ); 10 | var page = 1; 11 | var usersearch_list; 12 | var scrollPos = null; 13 | var users = {}; 14 | 15 | cp.SetIcon( 'icon-search' ); 16 | 17 | //////////////////////////////////////////////////////////// 18 | // リスト部作成 19 | //////////////////////////////////////////////////////////// 20 | var ListMake = function( type ) { 21 | var param = { 22 | type: 'GET', 23 | url: ApiUrl( '1.1' ) + 'users/search.json', 24 | data: { 25 | q: cp.param['q'], 26 | count: 20, 27 | page: page, 28 | }, 29 | }; 30 | 31 | if ( type == 'init' || type == 'reload' ) 32 | { 33 | param.data.page = 1; 34 | } 35 | 36 | cont.activity( { color: '#ffffff' } ); 37 | 38 | SendRequest( 39 | { 40 | action: 'oauth_send', 41 | acsToken: g_cmn.account[cp.param['account_id']]['accessToken'], 42 | acsSecret: g_cmn.account[cp.param['account_id']]['accessSecret'], 43 | param: param, 44 | id: cp.param['account_id'] 45 | }, 46 | function( res ) 47 | { 48 | if ( res.status == 200 ) 49 | { 50 | var s = ''; 51 | var json = res.json; 52 | var items = new Array(); 53 | var len = 0; 54 | var created_at = ''; 55 | 56 | for ( var i = 0, _len = json.length ; i < _len ; i++ ) 57 | { 58 | if ( users[json[i].id_str] ) 59 | { 60 | continue; 61 | } 62 | else 63 | { 64 | len++; 65 | users[json[i].id_str] = true; 66 | } 67 | 68 | // 日付にはとりあえずアカウントの作成日を設定 69 | created_at = json[i].created_at; 70 | 71 | // 最新ツイートが設定されている場合は、そのツイートの日時を設定 72 | if ( json[i].status != undefined ) 73 | { 74 | if ( json[i].status.created_at != undefined ) 75 | { 76 | created_at = json[i].status.created_at; 77 | } 78 | } 79 | 80 | var isfriend = IsFriend( cp.param['account_id'], json[i].id_str ); 81 | var isfollower = IsFollower( cp.param['account_id'], json[i].id_str ); 82 | 83 | const dt = new Date() 84 | const cr = DateConv( created_at, 0 ) 85 | const compdate = CompareDate( dt.getFullYear(), dt.getMonth() + 1, dt.getDate(), 86 | cr.substring( 0, 4 ), cr.substring( 5, 7 ), cr.substring( 8, 10 ) ); 87 | 88 | items.push( { 89 | icon: json[i].profile_image_url_https, 90 | screen_name: json[i].screen_name, 91 | name: twemoji.parse( json[i].name ), 92 | follow: NumFormat( json[i].friends_count ), 93 | follower: NumFormat( json[i].followers_count ), 94 | count: NumFormat( json[i].statuses_count ), 95 | description: json[i].description, 96 | verified: json[i].verified, 97 | protected: json[i].protected, 98 | user_id: json[i].id_str, 99 | created_at: created_at, 100 | ismutual: isfriend & isfollower, 101 | isfriend: isfriend & !isfollower, 102 | isfollower: !isfriend & isfollower, 103 | latest_date: ( json[i].status && json[i].status.created_at ) ? DateConv( json[i].status.created_at, 0 ) : null, 104 | sleeping: ( compdate > 30 ) 105 | } ); 106 | } 107 | 108 | s = OutputTPL( 'user_list', { items: items } ); 109 | 110 | // もっと読む 111 | var AppendReadmore = function() { 112 | if ( len > 0 ) 113 | { 114 | usersearch_list.append( 115 | '
' ); 116 | } 117 | }; 118 | 119 | switch ( type ) 120 | { 121 | // 初期、更新 122 | case 'init': 123 | case 'reload': 124 | usersearch_list.html( s ); 125 | usersearch_list.scrollTop( 0 ); 126 | 127 | page++; 128 | AppendReadmore(); 129 | break; 130 | // もっと読む 131 | case 'old': 132 | if ( len > 0 ) 133 | { 134 | usersearch_list.append( s ); 135 | 136 | page++; 137 | AppendReadmore(); 138 | } 139 | 140 | usersearch_list.find( '.readmore' ).first().remove(); 141 | $( '#tooltip' ).hide(); 142 | 143 | break; 144 | } 145 | 146 | cont.trigger( 'contents_resize' ); 147 | } 148 | else 149 | { 150 | // もっと読むで404が返ってきた場合 151 | if ( type == 'old' && res.status == 404 ) 152 | { 153 | usersearch_list.find( '.readmore' ).first().remove(); 154 | $( '#tooltip' ).hide(); 155 | } 156 | else 157 | { 158 | ApiError( i18nGetMessage( 'i18n_0213' ), res ); 159 | 160 | if ( type == 'old' ) 161 | { 162 | usersearch_list.find( '.readmore' ).removeClass( 'disabled' ); 163 | } 164 | } 165 | } 166 | 167 | cont.activity( false ); 168 | 169 | $( 'panel' ).find( 'div.contents' ).trigger( 'api_remaining_update', [cp.param['account_id']] ); 170 | } 171 | ); 172 | }; 173 | 174 | //////////////////////////////////////////////////////////// 175 | // 開始処理 176 | //////////////////////////////////////////////////////////// 177 | this.start = function() { 178 | //////////////////////////////////////// 179 | // 最小化/設定切替時のスクロール位置 180 | // 保存/復元 181 | //////////////////////////////////////// 182 | cont.on( 'contents_scrollsave', function( e, type ) { 183 | // 保存 184 | if ( type == 0 ) 185 | { 186 | if ( scrollPos == null ) 187 | { 188 | scrollPos = usersearch_list.scrollTop(); 189 | } 190 | } 191 | // 復元 192 | else 193 | { 194 | if ( scrollPos != null ) 195 | { 196 | usersearch_list.scrollTop( scrollPos ); 197 | scrollPos = null; 198 | } 199 | } 200 | } ); 201 | 202 | //////////////////////////////////////// 203 | // リサイズ処理 204 | //////////////////////////////////////// 205 | cont.on( 'contents_resize', function() { 206 | cont.find( '.usersearch_list' ).height( cont.height() - cont.find( '.panel_btns' ).height() - 1 ); 207 | } ); 208 | 209 | //////////////////////////////////////// 210 | // アカウント変更 211 | //////////////////////////////////////// 212 | cont.on( 'account_change', function( e, account_id ) { 213 | if ( cp.param['account_id'] == account_id ) 214 | { 215 | } 216 | else 217 | { 218 | p.find( 'div.titlebar' ).find( '.titlename' ).text( g_cmn.account[account_id].screen_name ); 219 | cp.param['account_id'] = account_id; 220 | 221 | cp.title = cp.title.replace( /().*(<\/span>)/, 222 | '$1' + g_cmn.account[account_id].screen_name + '$2' ); 223 | 224 | // パネルリストの更新" 225 | $( document ).trigger( 'panellist_changed' ); 226 | 227 | // 更新 228 | cont.find( '.panel_btns' ).find( '.usersearch_reload' ).trigger( 'click' ); 229 | } 230 | } ); 231 | 232 | //////////////////////////////////////// 233 | // このパネルを開いたアカウントが 234 | // 削除された場合 235 | //////////////////////////////////////// 236 | var AccountAliveCheck = function() { 237 | if ( g_cmn.account[cp.param['account_id']] == undefined ) 238 | { 239 | // パネルを閉じる 240 | p.find( '.close' ).trigger( 'click', [false] ); 241 | return false; 242 | } 243 | 244 | return true; 245 | }; 246 | 247 | //////////////////////////////////////// 248 | // アカウント情報更新 249 | //////////////////////////////////////// 250 | cont.on( 'account_update', function() { 251 | AccountAliveCheck(); 252 | 253 | // アカウント選択リスト更新 254 | var s = ''; 255 | var id; 256 | 257 | for ( var i = 0, _len = g_cmn.account_order.length ; i < _len ; i++ ) 258 | { 259 | id = g_cmn.account_order[i]; 260 | s += '' + g_cmn.account[id].screen_name + ''; 261 | } 262 | 263 | p.find( 'div.titlebar' ).find( '.titlename_list' ).html( s ) 264 | .find( 'span' ).click( function( e ) { 265 | p.find( 'div.contents' ).trigger( 'account_change', [$( this ).attr( 'account_id' )] ); 266 | $( this ).parent().hide(); 267 | } ); 268 | } ); 269 | 270 | if ( !AccountAliveCheck() ) 271 | { 272 | return; 273 | } 274 | 275 | // 全体を作成 276 | cont.addClass( 'usersearch' ) 277 | .html( OutputTPL( 'usersearch', {} ) ); 278 | 279 | usersearch_list = cont.find( '.usersearch_list' ); 280 | 281 | cp.SetTitle( i18nGetMessage( 'i18n_0105', [cp.param['q']] ) + ' (' + g_cmn.account[cp.param['account_id']]['screen_name'] + ')', false ); 282 | 283 | //////////////////////////////////////// 284 | // 更新ボタンクリック 285 | //////////////////////////////////////// 286 | cont.find( '.panel_btns' ).find( '.usersearch_reload' ).click( function( e ) { 287 | // disabledなら処理しない 288 | if ( $( this ).hasClass( 'disabled' ) ) 289 | { 290 | return; 291 | } 292 | 293 | ListMake( 'reload' ); 294 | } ); 295 | 296 | //////////////////////////////////////// 297 | // ユーザ名クリック 298 | //////////////////////////////////////// 299 | usersearch_list.on( 'click', '> div.item .screen_name', function( e ) { 300 | OpenUserTimeline( $( this ).text(), cp.param['account_id'] ); 301 | e.stopPropagation(); 302 | } ); 303 | 304 | //////////////////////////////////////// 305 | // アイコンクリック処理 306 | //////////////////////////////////////// 307 | usersearch_list.on( 'click', '> div.item .icon img', function( e ) { 308 | OpenUserShow( $( this ).parent().parent().attr( 'screen_name' ), 309 | $( this ).parent().parent().attr( 'user_id' ), 310 | cp.param['account_id'] ); 311 | 312 | e.stopPropagation(); 313 | } ); 314 | 315 | //////////////////////////////////////// 316 | // もっと読むクリック処理 317 | //////////////////////////////////////// 318 | usersearch_list.on( 'click', '> div.readmore', function( e ) { 319 | // disabledなら処理しない 320 | if ( $( this ).hasClass( 'disabled' ) ) 321 | { 322 | return; 323 | } 324 | 325 | $( this ).addClass( 'disabled' ); 326 | 327 | ListMake( 'old' ); 328 | 329 | e.stopPropagation(); 330 | } ); 331 | 332 | //////////////////////////////////////// 333 | // アイコンにカーソルを乗せたとき 334 | //////////////////////////////////////// 335 | usersearch_list.on( 'mouseenter mouseleave', '> div.item div.icon > img', function( e ) { 336 | if ( e.type == 'mouseenter' ) 337 | { 338 | // Draggableの設定をする 339 | SetDraggable( $( this ), p, cp ); 340 | } 341 | else 342 | { 343 | $( '#tooltip' ).hide(); 344 | } 345 | } ); 346 | 347 | //////////////////////////////////////// 348 | // 一番下までスクロールで 349 | // 「もっと読む」クリック 350 | //////////////////////////////////////// 351 | usersearch_list.scroll( 352 | function() 353 | { 354 | if ( g_cmn.cmn_param['autoreadmore'] == 1 ) 355 | { 356 | if ( usersearch_list.prop( 'scrollHeight' ) == usersearch_list.scrollTop() + usersearch_list.innerHeight() ) 357 | { 358 | usersearch_list.find( '.readmore' ).trigger( 'click' ); 359 | } 360 | } 361 | } 362 | ); 363 | 364 | // リスト部作成処理 365 | ListMake( 'init' ); 366 | }; 367 | 368 | //////////////////////////////////////////////////////////// 369 | // 終了処理 370 | //////////////////////////////////////////////////////////// 371 | this.stop = function() { 372 | }; 373 | } 374 | -------------------------------------------------------------------------------- /js/lib/twemoji.js: -------------------------------------------------------------------------------- 1 | /*! Copyright Twitter Inc. and other contributors. Licensed under MIT */ 2 | var twemoji=function(){"use strict";var twemoji={base:"https://twemoji.maxcdn.com/v/13.0.2/",ext:".png",size:"72x72",className:"emoji",convert:{fromCodePoint:fromCodePoint,toCodePoint:toCodePoint},onerror:function onerror(){if(this.parentNode){this.parentNode.replaceChild(createText(this.alt,false),this)}},parse:parse,replace:replace,test:test},escaper={"&":"&","<":"<",">":">","'":"'",'"':"""},re=/(?:\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,UFE0Fg=/\uFE0F/g,U200D=String.fromCharCode(8205),rescaper=/[&<>'"]/g,shouldntBeParsed=/^(?:iframe|noframes|noscript|script|select|style|textarea)$/,fromCharCode=String.fromCharCode;return twemoji;function createText(text,clean){return document.createTextNode(clean?text.replace(UFE0Fg,""):text)}function escapeHTML(s){return s.replace(rescaper,replacer)}function defaultImageSrcGenerator(icon,options){return"".concat(options.base,options.size,"/",icon,options.ext)}function grabAllTextNodes(node,allText){var childNodes=node.childNodes,length=childNodes.length,subnode,nodeType;while(length--){subnode=childNodes[length];nodeType=subnode.nodeType;if(nodeType===3){allText.push(subnode)}else if(nodeType===1&&!("ownerSVGElement"in subnode)&&!shouldntBeParsed.test(subnode.nodeName.toLowerCase())){grabAllTextNodes(subnode,allText)}}return allText}function grabTheRightIcon(rawText){return toCodePoint(rawText.indexOf(U200D)<0?rawText.replace(UFE0Fg,""):rawText)}function parseNode(node,options){var allText=grabAllTextNodes(node,[]),length=allText.length,attrib,attrname,modified,fragment,subnode,text,match,i,index,img,rawText,iconId,src;while(length--){modified=false;fragment=document.createDocumentFragment();subnode=allText[length];text=subnode.nodeValue;i=0;while(match=re.exec(text)){index=match.index;if(index!==i){fragment.appendChild(createText(text.slice(i,index),true))}rawText=match[0];iconId=grabTheRightIcon(rawText);i=index+rawText.length;src=options.callback(iconId,options);if(iconId&&src){img=new Image;img.onerror=options.onerror;img.setAttribute("draggable","false");attrib=options.attributes(rawText,iconId);for(attrname in attrib){if(attrib.hasOwnProperty(attrname)&&attrname.indexOf("on")!==0&&!img.hasAttribute(attrname)){img.setAttribute(attrname,attrib[attrname])}}img.className=options.className;img.alt=rawText;img.src=src;modified=true;fragment.appendChild(img)}if(!img)fragment.appendChild(createText(rawText,false));img=null}if(modified){if(i")}return ret})}function replacer(m){return escaper[m]}function returnNull(){return null}function toSizeSquaredAsset(value){return typeof value==="number"?value+"x"+value:value}function fromCodePoint(codepoint){var code=typeof codepoint==="string"?parseInt(codepoint,16):codepoint;if(code<65536){return fromCharCode(code)}code-=65536;return fromCharCode(55296+(code>>10),56320+(code&1023))}function parse(what,how){if(!how||typeof how==="function"){how={callback:how}}return(typeof what==="string"?parseString:parseNode)(what,{callback:how.callback||defaultImageSrcGenerator,attributes:typeof how.attributes==="function"?how.attributes:returnNull,base:typeof how.base==="string"?how.base:twemoji.base,ext:how.ext||twemoji.ext,size:how.folder||toSizeSquaredAsset(how.size||twemoji.size),className:how.className||twemoji.className,onerror:how.onerror||twemoji.onerror})}function replace(text,callback){return String(text).replace(re,callback)}function test(text){re.lastIndex=0;var result=re.test(text);re.lastIndex=0;return result}function toCodePoint(unicodeSurrogates,sep){var r=[],c=0,p=0,i=0;while(i 0 ) 258 | { 259 | setting.find( '.feed_append' ).removeClass( 'disabled' ); 260 | } 261 | else 262 | { 263 | setting.find( '.feed_append' ).addClass( 'disabled' ); 264 | } 265 | } ); 266 | 267 | //////////////////////////////////////// 268 | // 適用ボタンクリック処理 269 | //////////////////////////////////////// 270 | setting.find( '.rsssetting_apply' ).click( function( e ) { 271 | // disabedなら処理しない 272 | if ( $( this ).hasClass( 'disabled' ) ) 273 | { 274 | return; 275 | } 276 | 277 | // タイトル 278 | var title = setting.find( '.set_title' ).val(); 279 | 280 | if ( title.length <= 0 ) 281 | { 282 | MessageBox( i18nGetMessage( 'i18n_0076' ) ); 283 | setting.find( '.set_title' ).focus(); 284 | return false; 285 | } 286 | 287 | cp.param['title'] = title; 288 | cp.SetTitle( title, true ); 289 | 290 | // 新着読み込み 291 | cp.param['reload_time'] = setting.find( '.set_reload_time' ).slider( 'value' ); 292 | 293 | var _cp = { 294 | param: { 295 | count: cp.param['count'], 296 | showdesc: cp.param['showdesc'] 297 | } 298 | }; 299 | 300 | // 取得エントリ数 301 | cp.param['count'] = setting.find( '.set_count' ).slider( 'value' ); 302 | 303 | // 説明表示 304 | cp.param['showdesc'] = setting.find( '.set_showdesc' ).prop( 'checked' ) ? 1 : 0; 305 | 306 | if ( _cp.param['count'] != cp.param['count'] || _cp.param['showdesc'] != cp.param['showdesc'] ) 307 | { 308 | feedchange = true; 309 | } 310 | 311 | rss_list.trigger( 'reload_timer' ); 312 | 313 | setting.find( '.rsssetting_apply' ).addClass( 'disabled' ); 314 | 315 | if ( feedchange ) 316 | { 317 | feedchange = false; 318 | ListMake(); 319 | p.find( 'div.titlebar' ).find( '.setting' ).trigger( 'click' ); 320 | } 321 | 322 | // RSSパネル管理に登録 323 | var _id = cp.id.replace( /^panel_/, '' ); 324 | 325 | g_cmn.rss_panel[_id] = { 326 | id: _id, 327 | param: cp.param, 328 | }; 329 | 330 | // RSSパネル一覧を表示している場合は一覧更新 331 | var pid = IsUnique( 'rsslist' ); 332 | 333 | if ( pid != null ) 334 | { 335 | $( '#rsslist_reload' ).trigger( 'click' ); 336 | SetFront( p ); 337 | } 338 | 339 | SaveData(); 340 | 341 | e.stopPropagation(); 342 | } ); 343 | 344 | //////////////////////////////////////// 345 | // 登録ボタンクリック処理 346 | //////////////////////////////////////// 347 | setting.find( '.feed_append' ).click( function( e ) { 348 | // disabedなら処理しない 349 | if ( $( this ).hasClass( 'disabled' ) ) 350 | { 351 | return; 352 | } 353 | 354 | var url = setting.find( '.set_feed' ).val(); 355 | 356 | // 登録済み? 357 | for ( var i = 0, _len = cp.param['urls'].length ; i < _len ; i++ ) 358 | { 359 | if ( cp.param['urls'][i].url == url ) 360 | { 361 | MessageBox( i18nGetMessage( 'i18n_0257' ) ); 362 | setting.find( '.set_feed' ).focus(); 363 | return; 364 | } 365 | } 366 | 367 | setting.find( '.rsssetting_items .kinditems' ).last().activity( { color: '#ffffff' } ); 368 | setting.find( '.feed_append' ).addClass( 'disabled' ); 369 | 370 | SendRequest( 371 | { 372 | action: 'feed', 373 | url: url, 374 | count: 1, 375 | index: 0, 376 | }, 377 | function( res ) 378 | { 379 | if ( res.items[0].feedtitle == '' || res.items[0].feedlink == '' ) 380 | { 381 | MessageBox( i18nGetMessage( 'i18n_0064' ) ); 382 | setting.find( '.set_feed' ).focus(); 383 | setting.find( '.feed_append' ).removeClass( 'disabled' ); 384 | 385 | setting.find( '.rsssetting_items .kinditems' ).last().activity( false ); 386 | } 387 | else 388 | { 389 | feedchange = true; 390 | cp.param['urls'].push( { url: res.url, title: res.items[0].feedtitle } ); 391 | setting.find( '.rsssetting_apply' ).removeClass( 'disabled' ) 392 | .end() 393 | .find( '.set_feed' ).val( '' ).focus(); 394 | 395 | // タイトル未設定の場合はフィードのタイトルを設定 396 | var tit = setting.find( '.set_title' ); 397 | 398 | if ( ( tit.val() == 'RSS' || tit.val() == '' ) && res.items[0].feedtitle ) 399 | { 400 | tit.val( res.items[0].feedtitle ); 401 | } 402 | 403 | FeedList(); 404 | 405 | setting.find( '.rsssetting_items .kinditems' ).last().activity( false ); 406 | } 407 | } 408 | ); 409 | 410 | e.stopPropagation(); 411 | } ); 412 | 413 | //////////////////////////////////////// 414 | // 分類部クリック処理 415 | //////////////////////////////////////// 416 | setting.find( '.kind' ).click( function( e ) { 417 | var img_off = 'icon-play'; 418 | var img_on = 'icon-arrow_down'; 419 | 420 | if ( $( this ).find( '> span' ).hasClass( img_on ) ) 421 | { 422 | $( this ).find( '> span' ).removeClass( img_on ).addClass( img_off ) 423 | .end() 424 | .next().slideUp( 0 ); 425 | } 426 | else 427 | { 428 | $( this ).find( '> span' ).removeClass( img_off ).addClass( img_on ) 429 | .end() 430 | .next().slideDown( 200 ); 431 | } 432 | 433 | e.stopPropagation(); 434 | } ); 435 | } 436 | 437 | //////////////////////////////////////////////////////////// 438 | // 終了処理 439 | //////////////////////////////////////////////////////////// 440 | this.stop = function() { 441 | if ( tm != null ) 442 | { 443 | clearTimeout( tm ); 444 | tm = null; 445 | } 446 | }; 447 | } 448 | --------------------------------------------------------------------------------