root/lang/javascript/userscripts/tophatenar_view.user.js

Revision 22297, 9.0 kB (checked in by drry, 16 months ago)
  • (some of the tiny trivial changes)
Line 
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>&lt;相関グラフ&gt;</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>&lt;購読者数の推移&gt;</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>&lt;ブックマーク数の推移&gt;</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})();
Note: See TracBrowser for help on using the browser.