1 var nmbug_server = 'http://localhost:5000';
4 show: function (message_id) {
6 this._get_available_tags(function (available_tags) {
9 _this._edit_tags.bind(_this, available_tags, message_id));
12 _get_available_tags: function (callback) {
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);
25 throw 'Error fetching ' + url + ' (status ' + this.status + ')';
28 request.open('get', url, true);
31 _get_tags: function (message_id, callback) {
35 encodeURIComponent(message_id),
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);
45 throw 'Error fetching ' + url + ' (status ' + this.status + ')';
48 request.open('get', url, true);
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);
58 function basename (element) {
60 if (!element.tagName) {
62 } else if (element.tagName.toLowerCase() == 'script') {
64 } else if (element.tagName.toLowerCase() == 'link') {
69 return url.replace(/.*\//, '');
73 var name = basename(this);
74 console.log('nmbug: loaded ' + name, this);
75 var index = needed.indexOf(name);
77 needed.splice(index, 1);
79 if (needed.length == 0) {
80 _this._x_edit_tags(available_tags, message_id, tags);
84 function has_header (name) {
85 var nodes = document.head.childNodes;
86 for (var i = 0; i < nodes.length; i++) {
87 if (basename(nodes[i]) == name) {
94 if (!has_header('dialog-polyfill.js')) {
95 needed.push('dialog-polyfill.js');
96 var script = document.createElement('script');
97 script.type = 'text/javascript';
98 script.src = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.js';
99 script.onload = onload;
100 console.log('nmbug: loading dialog-polyfill.js');
101 document.head.appendChild(script);
104 if (!has_header('dialog-polyfill.css')) {
105 needed.push('dialog-polyfill.css');
106 var link = document.createElement('link');
107 link.rel = 'stylesheet';
108 link.type = 'text/css';
109 link.href = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.css';
110 link.onload = onload;
111 console.log('nmbug: loading dialog-polyfill.css');
112 document.head.appendChild(link);
116 _x_edit_tags: function (available_tags, message_id, tags) {
117 var dialog = document.createElement('dialog');
118 if (!document.createElement('dialog').show) {
119 dialogPolyfill.registerDialog(dialog);
122 dialog.style.border = '1px solid rgba(0, 0, 0, 0.3)';
123 dialog.style.borderRadius = '6px';
124 dialog.style.boxShadow = '0 3px 7px rgba(0, 0, 0, 0.3)';
126 var content = document.createElement('p');
127 content.innerHTML = 'Edit tags for ' + message_id;
128 dialog.appendChild(content);
130 var ul = document.createElement('ul');
131 dialog.appendChild(ul);
132 for (var i = 0; i < available_tags.length; i++) {
133 var li = document.createElement('li');
134 li.innerHTML = available_tags[i];
135 li.style.cursor = 'pointer';
136 if (tags.indexOf(available_tags[i]) >= 0) {
137 li.style.backgroundColor = 'lime';
139 li.onclick = this._toggle_tag.bind(
140 this, message_id, available_tags[i], li);
143 var close = document.createElement('button');
144 close.innerHTML = 'Close';
145 close.onclick = function () {
148 dialog.appendChild(close);
150 document.body.appendChild(dialog);
154 _toggle_tag: function (message_id, tag, li) {
156 if (li.style.backgroundColor == 'lime') {
157 prefix = '-'; /* unset */
158 li.style.backgroundColor = null;
160 prefix = '+'; /* set */
161 li.style.backgroundColor = 'lime';
166 encodeURIComponent(message_id),
168 console.log('nmbug: alter tags via ' + url);
169 var request = new XMLHttpRequest();
170 request.onload = function () {
171 if (this.status == 200) {
172 var tags = JSON.parse(this.response);
173 console.log('nmbug: got tags', tags);
175 throw 'Error posting to ' + url + ' (status ' + this.status + ')';
178 request.open('post', url, true);
179 request.setRequestHeader(
180 'Content-Type', 'application/json; charset=UTF-8');
181 request.send(JSON.stringify([prefix + tag]));
185 var _gmane_handler = {
186 regexp: /gmane[.]org/,
187 handle: function (callback) {
188 var article = this._get_article();
189 this._get_message_id(article, callback);
191 _article_from_url: function (url) {
192 var regexp = new RegExp('http://article.gmane.org/([^/]+)/([0-9]+)');
193 var match = regexp.exec(url);
194 console.log('nmbug: get article from ' + url, match);
196 return {'group': match[1], 'id': parseInt(match[2])};
199 _get_article: function () {
200 var article = this._article_from_url(document.URL);
202 for (var i = 0; !article && i < window.frames.length; i++) {
203 article = this._article_from_url(window.frames[i].document.URL);
206 throw "Cannot extract an article from Gmane's " + document.URL;
210 _get_message_id: function (article, callback) {
217 console.log('nmbug: get Message-ID from ' + url);
218 var request = new XMLHttpRequest();
219 request.onload = function () {
220 var message_id = this.responseText;
221 callback(message_id);
223 request.open('get', url, true);
232 function _check_handler(handler) {
233 var match = handler.regexp.test(document.URL);
234 console.log('nmbug: testing', handler, match);
236 console.log('nmbug: matched', handler);
237 handler.handle(nmbug.show.bind(nmbug));
239 return match; /* break after the first match */
243 var matched = handlers.some(_check_handler);
245 throw 'No handler for ' + document.URL;