1 var nmbug_server = 'http://localhost:5000';
4 show: function (message_id, frame) {
6 if (frame === undefined) {
9 this._get_available_tags(function (available_tags) {
12 _this._edit_tags.bind(_this, frame, available_tags, message_id));
15 _get_available_tags: function (callback) {
20 console.log('nmbug: get available tags from ' + url);
21 var request = new XMLHttpRequest();
22 request.onload = function () {
23 if (this.status == 200) {
24 var available_tags = JSON.parse(this.response);
25 console.log('nmbug: got available tags', available_tags);
26 callback(available_tags);
28 throw 'Error fetching ' + url + ' (status ' + this.status + ')';
31 request.open('get', url, true);
34 _get_tags: function (message_id, callback) {
38 encodeURIComponent(message_id),
40 console.log('nmbug: get tags from ' + url);
41 var request = new XMLHttpRequest();
42 request.onload = function () {
43 if (this.status == 200) {
44 var tags = JSON.parse(this.response);
45 console.log('nmbug: got tags', tags);
48 throw 'Error fetching ' + url + ' (status ' + this.status + ')';
51 request.open('get', url, true);
54 _edit_tags: function (frame, available_tags, message_id, tags) {
55 var have_dialog_polyfill;
57 have_dialog_polyfill = frame.dialogPolyfill !== undefined;
59 if (error.name == 'ReferenceError') {
60 have_dialog_polyfill = false;
63 if (frame.document.createElement('dialog').show || have_dialog_polyfill) {
64 this._x_edit_tags(frame, available_tags, message_id, tags);
66 var script = frame.document.createElement('script');
67 script.type = 'text/javascript';
68 script.src = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.js';
70 console.log('nmbug: loading dialog-polyfill.js');
71 frame.document.head.appendChild(script);
73 var link = frame.document.createElement('link');
74 link.rel = 'stylesheet';
75 link.type = 'text/css';
76 link.href = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.css';
78 console.log('nmbug: loading dialog-polyfill.css');
79 frame.document.head.appendChild(link);
82 function edit_tags_after_dialog_polyfill () {
84 have_dialog_polyfill = frame.dialogPolyfill !== undefined;
85 console.log('have dialogPolyfill');
87 _this._x_edit_tags.bind(_this), 200,
88 frame, available_tags, message_id, tags);
90 if (error.name == 'ReferenceError') {
91 console.log('waiting for dialogPolyfill');
92 window.setTimeout(edit_tags_after_dialog_polyfill, 200);
96 edit_tags_after_dialog_polyfill();
99 _x_edit_tags: function (frame, available_tags, message_id, tags) {
100 var dialog = frame.document.createElement('dialog');
101 if (!frame.document.createElement('dialog').show) {
102 frame.dialogPolyfill.registerDialog(dialog);
105 dialog.style.border = '1px solid rgba(0, 0, 0, 0.3)';
106 dialog.style.borderRadius = '6px';
107 dialog.style.boxShadow = '0 3px 7px rgba(0, 0, 0, 0.3)';
109 var content = frame.document.createElement('p');
110 content.innerHTML = 'Edit tags for ' + message_id;
111 dialog.appendChild(content);
113 var tag_list = frame.document.createElement('p');
114 dialog.appendChild(tag_list);
115 for (var i = 0; i < available_tags.length; i++) {
116 var tag = frame.document.createElement('a');
117 tag.innerHTML = available_tags[i];
118 tag.style.cursor = 'pointer';
119 if (tags.indexOf(available_tags[i]) >= 0) {
120 tag.style.backgroundColor = 'lime';
122 tag.onclick = this._toggle_tag.bind(
123 this, message_id, available_tags[i], tag);
124 tag_list.appendChild(tag);
125 tag_list.appendChild(frame.document.createTextNode(' '));
127 var close = frame.document.createElement('button');
128 close.innerHTML = 'Close';
129 close.onclick = function () {
132 dialog.appendChild(close);
134 frame.document.body.insertBefore(dialog, frame.document.body.firstChild);
138 _toggle_tag: function (message_id, tag, element) {
140 if (element.style.backgroundColor == 'lime') {
141 prefix = '-'; /* unset */
142 element.style.backgroundColor = null;
144 prefix = '+'; /* set */
145 element.style.backgroundColor = 'lime';
150 encodeURIComponent(message_id),
152 console.log('nmbug: alter tags via ' + url);
153 var request = new XMLHttpRequest();
154 request.onload = function () {
155 if (this.status == 200) {
156 var tags = JSON.parse(this.response);
157 console.log('nmbug: got tags', tags);
159 throw 'Error posting to ' + url + ' (status ' + this.status + ')';
162 request.open('post', url, true);
163 request.setRequestHeader(
164 'Content-Type', 'application/json; charset=UTF-8');
165 request.send(JSON.stringify([prefix + tag]));
169 var _gmane_handler = {
170 regexp: /gmane[.]org/,
171 handle: function (callback) {
172 var frame = this._get_frame();
173 var article = this._article_from_url(frame.document.URL);
174 this._get_message_id(article, function (message_id) {
175 callback(message_id, frame);
178 _article_from_url: function (url) {
179 var regexp = new RegExp('http://article.gmane.org/([^/]+)/([0-9]+)');
180 var match = regexp.exec(url);
181 console.log('nmbug: get article from ' + url, match);
183 return {'group': match[1], 'id': parseInt(match[2])};
186 _get_frame: function () {
188 var article = this._article_from_url(frame.document.URL);
190 for (var i = 0; !article && i < window.frames.length; i++) {
191 frame = window.frames[i];
192 article = this._article_from_url(frame.document.URL);
195 throw "Cannot extract an article from Gmane's " + document.URL;
199 _get_message_id: function (article, callback) {
206 console.log('nmbug: get Message-ID from ' + url);
207 var request = new XMLHttpRequest();
208 request.onload = function () {
209 var message_id = this.responseText;
210 callback(message_id);
212 request.open('get', url, true);
221 function _check_handler(handler) {
222 var match = handler.regexp.test(document.URL);
223 console.log('nmbug: testing', handler, match);
225 console.log('nmbug: matched', handler);
226 handler.handle(nmbug.show.bind(nmbug));
228 return match; /* break after the first match */
232 var matched = handlers.some(_check_handler);
234 throw 'No handler for ' + document.URL;