nmbug.js: Add tag-toggling with a stub _toggle_tag
[nmhive.git] / nmbug.js
1 var nmbug_server = 'http://localhost:5000';
2
3 nmbug = {
4         show: function (message_id) {
5                 var _this = this;
6                 this._get_available_tags(function (available_tags) {
7                         _this._get_tags(
8                                 message_id,
9                                 _this._edit_tags.bind(_this, available_tags, message_id));
10                 });
11         },
12         _get_available_tags: function (callback) {
13                 var url = [
14                         nmbug_server,
15                         'tags',
16                         ].join('/');
17                 console.log('nmbug: get available tags from ' + url);
18                 var request = new XMLHttpRequest();
19                 request.onload = function () {
20                         if (this.status == 200) {
21                                 var available_tags = JSON.parse(this.response);
22                                 console.log('nmbug: got available tags', available_tags);
23                                 callback(available_tags);
24                         } else {
25                                 throw 'Error fetching ' + url + ' (status ' + this.status + ')';
26                         }
27                 };
28                 request.open('get', url, true);
29                 request.send();
30         },
31         _get_tags: function (message_id, callback) {
32                 var url = [
33                         nmbug_server,
34                         'mid',
35                         encodeURIComponent(message_id),
36                         ].join('/');
37                 console.log('nmbug: get tags from ' + url);
38                 var request = new XMLHttpRequest();
39                 request.onload = function () {
40                         if (this.status == 200) {
41                                 var tags = JSON.parse(this.response);
42                                 console.log('nmbug: got tags', tags);
43                                 callback(tags);
44                         } else {
45                                 throw 'Error fetching ' + url + ' (status ' + this.status + ')';
46                         }
47                 };
48                 request.open('get', url, true);
49                 request.send();
50         },
51         _edit_tags: function (available_tags, message_id, tags) {
52                 if (document.createElement('dialog').show) {
53                         this._x_edit_tags(available_tags, message_id, tags);
54                 } else {
55                         var _this = this;
56                         var dialog_polyfill_loaded = 0;
57
58                         function onload () {
59                                 dialog_polyfill_loaded++;
60                                 if (dialog_polyfill_loaded == 2) {
61                                         _this._x_edit_tags(available_tags, message_id, tags);
62                                 }
63                         }
64
65                         var script = document.createElement('script');
66                         script.type = 'text/javascript';
67                         script.src = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.js';
68                         script.onload = onload;
69                         document.head.appendChild(script);
70
71                         var link = document.createElement('link');
72                         link.rel = 'stylesheet';
73                         link.type = 'text/css';
74                         link.href = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.css';
75                         link.onload = onload;
76                         document.head.appendChild(link);
77                 }
78         },
79         _x_edit_tags: function (available_tags, message_id, tags) {
80                 var dialog = document.createElement('dialog');
81                 if (!document.createElement('dialog').show) {
82                         dialogPolyfill.registerDialog(dialog);
83                 }
84
85                 dialog.style.border = '1px solid rgba(0, 0, 0, 0.3)';
86                 dialog.style.borderRadius = '6px';
87                 dialog.style.boxShadow = '0 3px 7px rgba(0, 0, 0, 0.3)';
88
89                 var content = document.createElement('p');
90                 content.innerHTML = 'Edit tags for ' + message_id;
91                 dialog.appendChild(content);
92
93                 var ul = document.createElement('ul');
94                 dialog.appendChild(ul);
95                 for (var i = 0; i < available_tags.length; i++) {
96                         var li = document.createElement('li');
97                         li.innerHTML = available_tags[i];
98                         li.style.cursor = 'pointer';
99                         if (tags.indexOf(available_tags[i]) >= 0) {
100                                 li.style.backgroundColor = 'lime';
101                         }
102                         li.onclick = this._toggle_tag.bind(
103                                 this, message_id, available_tags[i], li);
104                         ul.appendChild(li);
105                 }
106                 var close = document.createElement('button');
107                 close.innerHTML = 'Close';
108                 close.onclick = function () {
109                         dialog.close();
110                 };
111                 dialog.appendChild(close);
112
113                 document.body.appendChild(dialog);
114
115                 dialog.show();
116         },
117         _toggle_tag: function (message_id, tag, li) {
118                 alert('toggle ' + tag + ' for ' + message_id);
119         },
120 };
121
122 var _gmane_handler = {
123         regexp: /gmane[.]org/,
124         handle: function (callback) {
125                 var article = this._get_article();
126                 this._get_message_id(article, callback);
127         },
128         _article_from_url: function (url) {
129                 var regexp = new RegExp('http://article.gmane.org/([^/]+)/([0-9]+)');
130                 var match = regexp.exec(url);
131                 console.log('nmbug: get article from ' + url, match);
132                 if (match) {
133                         return {'group': match[1], 'id': parseInt(match[2])};
134                 }
135         },
136         _get_article: function () {
137                 var article = this._article_from_url(document.URL);
138                 var i = 0;
139                 for (var i = 0; !article && i < window.frames.length; i++) {
140                         article = this._article_from_url(window.frames[i].document.URL);
141                 }
142                 if (!article) {
143                         throw "Cannot extract an article from Gmane's " + document.URL;
144                 }
145                 return article;
146         },
147         _get_message_id: function (article, callback) {
148                 var url = [
149                         nmbug_server,
150                         'gmane',
151                         article.group,
152                         article.id,
153                 ].join('/');
154                 console.log('nmbug: get Message-ID from ' + url);
155                 var request = new XMLHttpRequest();
156                 request.onload = function () {
157                         var message_id = this.responseText;
158                         callback(message_id);
159                 };
160                 request.open('get', url, true);
161                 request.send();
162         },
163 };
164
165 var handlers = [
166         _gmane_handler,
167 ];
168
169 function _check_handler(handler) {
170         var match = handler.regexp.test(document.URL);
171         console.log('nmbug: testing', handler, match);
172         if (match) {
173                 console.log('nmbug: matched', handler);
174                 handler.handle(nmbug.show.bind(nmbug));
175         }
176         return match;  /* break after the first match */
177 }
178
179 function run() {
180         var matched = handlers.some(_check_handler);
181         if (!matched) {
182                 throw 'No handler for ' + document.URL;
183         }
184 }