| 1 | // ==UserScript==
|
|---|
| 2 | // @name TopHatenar View
|
|---|
| 3 | // @namespace http://d.hatena.ne.jp/yuroyoro/
|
|---|
| 4 | // @description show TopHatenar chart
|
|---|
| 5 | // @include http://d.hatena.ne.jp/*
|
|---|
| 6 | // ==/UserScript==
|
|---|
| 7 | //
|
|---|
| 8 | //
|
|---|
| 9 |
|
|---|
| 10 | (function() {
|
|---|
| 11 |
|
|---|
| 12 | var already_got_chart = false;
|
|---|
| 13 |
|
|---|
| 14 | if (self.location.href != top.location.href) {
|
|---|
| 15 | return;
|
|---|
| 16 | }
|
|---|
| 17 |
|
|---|
| 18 | GM_addStyle(<><![CDATA[
|
|---|
| 19 | div#TopHatenar_view{
|
|---|
| 20 | z-index: 250;
|
|---|
| 21 | position: fixed;
|
|---|
| 22 | bottom: 71px;
|
|---|
| 23 | left: 0px;
|
|---|
| 24 | overflow: hidden;
|
|---|
| 25 | opacity: 0.85;
|
|---|
| 26 | min-height: 20px;
|
|---|
| 27 | min-width: 20px;
|
|---|
| 28 | max-height: 400px;
|
|---|
| 29 | padding: 2px;
|
|---|
| 30 | -moz-border-radius: 0 8px 8px 0;
|
|---|
| 31 | font-family: Helvetica, Verdana, sans-serif;
|
|---|
| 32 | }
|
|---|
| 33 | div#TopHatenar_view table.TopHatenar_view_table{
|
|---|
| 34 | color: #CCCCCC;
|
|---|
| 35 | font-size: 12px;
|
|---|
| 36 | font-weight: bold;
|
|---|
| 37 | border: none;
|
|---|
| 38 | padding: 5px 10px;
|
|---|
| 39 | margin: 10px 10px 10px 10px;
|
|---|
| 40 | background-color: #333333;
|
|---|
| 41 | border-collapse: collapse;
|
|---|
| 42 | }
|
|---|
| 43 | div#TopHatenar_view table.TopHatenar_view_table td{
|
|---|
| 44 | padding: 0px 15px;
|
|---|
| 45 | background-color: #333333;
|
|---|
| 46 | white-space: nowrap;
|
|---|
| 47 | border: 1px solid #CCCCCC;
|
|---|
| 48 | }
|
|---|
| 49 | div#TopHatenar_view table.TopHatenar_view_table a{
|
|---|
| 50 | color: #CCCCCC;
|
|---|
| 51 | text-decoration: none;
|
|---|
| 52 | }
|
|---|
| 53 | div#TopHatenar_view span.TopHatenar_view_count{
|
|---|
| 54 | color: #6699ff;
|
|---|
| 55 | font-size: 14px
|
|---|
| 56 | }
|
|---|
| 57 | div#TopHatenar_view span.TopHatenar_view_rank{
|
|---|
| 58 | color: #ff6633;
|
|---|
| 59 | font-size: 14px
|
|---|
| 60 | }
|
|---|
| 61 | div#TopHatenar_view span.TopHatenar_view_percentile{
|
|---|
| 62 | color: #00cc99;
|
|---|
| 63 | font-size: 14px
|
|---|
| 64 | }
|
|---|
| 65 | ]]></>);
|
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 | function main() {
|
|---|
| 69 |
|
|---|
| 70 | var element = document.createElement('div');
|
|---|
| 71 | with (element) {
|
|---|
| 72 | id = 'TopHatenar_view';
|
|---|
| 73 | init_style(style);
|
|---|
| 74 | addEventListener('mouseover', show_TopHatenar_view, false);
|
|---|
| 75 | addEventListener('mouseout', hide_TopHatenar_view, false);
|
|---|
| 76 | }
|
|---|
| 77 | var logo = document.createElement('div');
|
|---|
| 78 | with (logo) {
|
|---|
| 79 | id = 'TopHatenar_view_logo';
|
|---|
| 80 | innerHTML = "T?";
|
|---|
| 81 | with (style) {
|
|---|
| 82 | margin = '0';
|
|---|
| 83 | padding = '2';
|
|---|
| 84 | fontSize = '16px';
|
|---|
| 85 | textAlign = 'center';
|
|---|
| 86 | color = '#FF6347';
|
|---|
| 87 | fontWeight = 'bold';
|
|---|
| 88 | }
|
|---|
| 89 | }
|
|---|
| 90 | element.appendChild(logo);
|
|---|
| 91 |
|
|---|
| 92 | var content = document.createElement('div');
|
|---|
| 93 | with (content) {
|
|---|
| 94 | id = 'TopHatenar_view_content';
|
|---|
| 95 | init_style(style);
|
|---|
| 96 | with (style) {
|
|---|
| 97 | display = 'none';
|
|---|
| 98 | margin = '7px 4px 4px 4px';
|
|---|
| 99 | width = '540px';
|
|---|
| 100 |
|
|---|
| 101 | }
|
|---|
| 102 | }
|
|---|
| 103 | element.appendChild(content);
|
|---|
| 104 |
|
|---|
| 105 | document.body.appendChild(element);
|
|---|
| 106 | }
|
|---|
| 107 |
|
|---|
| 108 | function show_TopHatenar_view() {
|
|---|
| 109 |
|
|---|
| 110 | if (!already_got_chart) {
|
|---|
| 111 | get_TopHatenar_chart();
|
|---|
| 112 | }
|
|---|
| 113 |
|
|---|
| 114 | var TopHatenar_view_logo = document.getElementById('TopHatenar_view_logo');
|
|---|
| 115 | TopHatenar_view_logo.style.display = 'none';
|
|---|
| 116 |
|
|---|
| 117 | var TopHatenar_view_elem = document.getElementById('TopHatenar_view_content');
|
|---|
| 118 | TopHatenar_view_elem.style.display = 'block';
|
|---|
| 119 | }
|
|---|
| 120 |
|
|---|
| 121 | function hide_TopHatenar_view() {
|
|---|
| 122 | var TopHatenar_view_elem = document.getElementById('TopHatenar_view_content');
|
|---|
| 123 | if (TopHatenar_view_elem) {
|
|---|
| 124 | TopHatenar_view_elem.style.display = 'none';
|
|---|
| 125 | var TopHatenar_view_logo = document.getElementById('TopHatenar_view_logo');
|
|---|
| 126 | TopHatenar_view_logo.style.display = 'block';
|
|---|
| 127 | }
|
|---|
| 128 | }
|
|---|
| 129 |
|
|---|
| 130 | function get_TopHatenar_chart() {
|
|---|
| 131 |
|
|---|
| 132 | var content = document.getElementById('TopHatenar_view_content');
|
|---|
| 133 |
|
|---|
| 134 | // HatenaIDを切り出す
|
|---|
| 135 | var m = /^http:\/\/d\.hatena\.ne\.jp\/([a-zA-Z][\w-]{1,30}[a-zA-Z\d])/.exec(top.location.href);
|
|---|
| 136 | var hatena_id = m[1];
|
|---|
| 137 |
|
|---|
| 138 | var detail_url = 'http://tophatenar.com/view/' + hatena_id; // 詳細ページURL
|
|---|
| 139 |
|
|---|
| 140 | // ID Link
|
|---|
| 141 | var id_link = document.createElement('a');
|
|---|
| 142 | with (id_link) {
|
|---|
| 143 | innerHTML = 'TopHatenar@' + hatena_id;
|
|---|
| 144 | setAttribute('href', detail_url);
|
|---|
| 145 | setAttribute('title', 'クリックで詳細情報ページへ');
|
|---|
| 146 | with (style) {
|
|---|
| 147 | fontSize = '20px';
|
|---|
| 148 | textAlign = 'center';
|
|---|
| 149 | color = '#FF6347';
|
|---|
| 150 | fontWeight = 'bold';
|
|---|
| 151 | margin = '5px';
|
|---|
| 152 | textDecoration = 'none';
|
|---|
| 153 | }
|
|---|
| 154 | }
|
|---|
| 155 | content.appendChild(id_link);
|
|---|
| 156 |
|
|---|
| 157 | // Ranking情報表示用
|
|---|
| 158 | var id_info = document.createElement('div');
|
|---|
| 159 | content.appendChild(id_info);
|
|---|
| 160 |
|
|---|
| 161 | // グラフを取得
|
|---|
| 162 | var correlation_chart = document.createElement('img');
|
|---|
| 163 | with (correlation_chart) {
|
|---|
| 164 | src = 'http://tophatenar.com/chart/correlation_small/' + hatena_id;
|
|---|
| 165 | title = "相関グラフ";
|
|---|
| 166 | init_img_style(style);
|
|---|
| 167 | }
|
|---|
| 168 | var correlation_chart_title = document.createElement('div');
|
|---|
| 169 | correlation_chart_title.style.cssFloat = 'left';
|
|---|
| 170 | correlation_chart_title.style.textAlign = 'center';
|
|---|
| 171 | correlation_chart_title.appendChild(correlation_chart);
|
|---|
| 172 | content.appendChild(correlation_chart_title);
|
|---|
| 173 | correlation_chart_title.innerHTML += "<p><相関グラフ></p>";
|
|---|
| 174 |
|
|---|
| 175 | var subscriber_chart = document.createElement('img');
|
|---|
| 176 | with (subscriber_chart) {
|
|---|
| 177 | src = 'http://tophatenar.com/chart/subscriber_small/' + hatena_id;
|
|---|
| 178 | title = "購読者数の推移";
|
|---|
| 179 | init_img_style(style);
|
|---|
| 180 | }
|
|---|
| 181 | var subscriber_chart_title = document.createElement('div');
|
|---|
| 182 | subscriber_chart_title.style.cssFloat = 'left';
|
|---|
| 183 | subscriber_chart_title.style.textAlign = 'center';
|
|---|
| 184 | subscriber_chart_title.appendChild(subscriber_chart);
|
|---|
| 185 | subscriber_chart_title.innerHTML += "<p><購読者数の推移></p>";
|
|---|
| 186 | content.appendChild(subscriber_chart_title);
|
|---|
| 187 |
|
|---|
| 188 | var bookmark_chart = document.createElement('img');
|
|---|
| 189 | with (bookmark_chart) {
|
|---|
| 190 | src = 'http://tophatenar.com/chart/bookmark_small/' + hatena_id;
|
|---|
| 191 | title = "ブックマーク数の推移";
|
|---|
| 192 | init_img_style(style);
|
|---|
| 193 | }
|
|---|
| 194 | var bookmark_chart_title = document.createElement('div');
|
|---|
| 195 | bookmark_chart_title.style.cssFloat = 'left';
|
|---|
| 196 | bookmark_chart_title.style.textAlign = 'center';
|
|---|
| 197 | bookmark_chart_title.appendChild(bookmark_chart);
|
|---|
| 198 | content.appendChild(bookmark_chart_title);
|
|---|
| 199 | bookmark_chart_title.innerHTML += "<p><ブックマーク数の推移></p>";
|
|---|
| 200 |
|
|---|
| 201 | // 詳細ページから情報取得
|
|---|
| 202 | GM_xmlhttpRequest({
|
|---|
| 203 | method : 'GET',
|
|---|
| 204 | url : detail_url,
|
|---|
| 205 | onload : function(res) {
|
|---|
| 206 | var html = res.responseText;
|
|---|
| 207 | var numbers = getTags(html, "div", "number");
|
|---|
| 208 | var ranks = getTags(html, "div", "rank");
|
|---|
| 209 | var percentiles = getTags(html, "div", "percentile");
|
|---|
| 210 |
|
|---|
| 211 | var subscriber_cnt = numbers[1].match(/\d+/gm);
|
|---|
| 212 | var subscriber_rank = ranks[0].match(/\d+/gm);
|
|---|
| 213 | var subscriber_percentile = percentiles[0].match(/[\d.]+/gm);
|
|---|
| 214 |
|
|---|
| 215 | var bookmark_cnt = numbers[2].match(/\d+\s+/gm);
|
|---|
| 216 | var bookmark_rank = ranks[1].match(/\d+/gm);
|
|---|
| 217 | var bookmark_percentile = percentiles[1].match(/[\d.]+/gm);
|
|---|
| 218 |
|
|---|
| 219 | var inner = "<table class='TopHatenar_view_table'><tbody><tr>";
|
|---|
| 220 | inner += "<td>購読者数 : <span class='TopHatenar_view_count'>" + subscriber_cnt + "</span></td>";
|
|---|
| 221 | inner += "<td><span class='TopHatenar_view_rank'>" + subscriber_rank[0] + "</span>位/" + subscriber_rank[1] + "人";
|
|---|
| 222 | inner += "<a href='/ranking/subscriber/" + subscriber_rank[0] + "'>[周辺ランキング]</a></td>";
|
|---|
| 223 | inner += "<td>(上位<span class='TopHatenar_view_percentile'>" +subscriber_percentile + "</span>%以内) </td>";
|
|---|
| 224 | inner += "</tr><tr>";
|
|---|
| 225 | inner += "<td>ブックマーク数 : <span class='TopHatenar_view_count'>" + bookmark_cnt + "</span></td>";
|
|---|
| 226 | inner += "<td><span class='TopHatenar_view_rank'>" + bookmark_rank[0] + "</span>位/" + bookmark_rank[1] + "人";
|
|---|
| 227 | inner += "<a href='/ranking/subscriber/" + bookmark_rank[0] + "'>[周辺ランキング]</a></td>";
|
|---|
| 228 | inner += "<td>(上位<span class='TopHatenar_view_percentile'>" +bookmark_percentile + "</span>%以内) </td>";
|
|---|
| 229 | inner += "</tr></tbody></table>"
|
|---|
| 230 |
|
|---|
| 231 | id_info.innerHTML += inner;
|
|---|
| 232 | }
|
|---|
| 233 | });
|
|---|
| 234 |
|
|---|
| 235 |
|
|---|
| 236 | already_got_chart = true;
|
|---|
| 237 |
|
|---|
| 238 |
|
|---|
| 239 | }
|
|---|
| 240 |
|
|---|
| 241 |
|
|---|
| 242 | function init_style(style) {
|
|---|
| 243 | with (style) {
|
|---|
| 244 | fontSize = '12px';
|
|---|
| 245 | textAlign = 'left';
|
|---|
| 246 | padding = 0;
|
|---|
| 247 | margin = 0;
|
|---|
| 248 | lineHeight = '15px';
|
|---|
| 249 | color = '#CCCCCC';
|
|---|
| 250 | backgroundColor = '#333333';
|
|---|
| 251 | border = 'none';
|
|---|
| 252 | }
|
|---|
| 253 | }
|
|---|
| 254 |
|
|---|
| 255 | function init_img_style(style) {
|
|---|
| 256 | with (style) {
|
|---|
| 257 | border = '1px solid #CCCCCC';
|
|---|
| 258 | margin = '5px';
|
|---|
| 259 | position = 'relative';
|
|---|
| 260 | textAlign = 'center';
|
|---|
| 261 | }
|
|---|
| 262 | }
|
|---|
| 263 |
|
|---|
| 264 | function getTags(html, tagName, className) {
|
|---|
| 265 | var cls = "";
|
|---|
| 266 | if (className) {
|
|---|
| 267 | cls = "(?:[ \\t\\r\\n][^>]*?)?[ \\t\\r\\n]class[ \\t\\r\\n]*=[ \\t\\r\\n]*([\"'])(?:(?:\\\\\\1|(?!\\1).)+?[ \\t\\r\\n]+)?" + className + "(?:[ \\t\\r\\n]+(?:\\\\\\1|(?!\\1).)+?)?\\1";
|
|---|
| 268 | }
|
|---|
| 269 | var reg = new RegExp("<" + tagName + cls + "(?:[ \\t\\r\\n][^>]*)?>(?:(?!<" + tagName + "\\b)[\\s\\S])*?</" + tagName + "[ \\t\\r\\n]*>", "ig");
|
|---|
| 270 | return html.match(reg);
|
|---|
| 271 | }
|
|---|
| 272 |
|
|---|
| 273 | main();
|
|---|
| 274 |
|
|---|
| 275 | })();
|
|---|