~minos-archive/minos/firefox-minos-settings

« back to all changes in this revision

Viewing changes to firefox27/firefox/h5xyzl6e.default/gm_scripts/LP_StockReplies-2/lp_stockreplies.user.js

  • Committer: Javier Lopez
  • Date: 2015-07-08 01:10:19 UTC
  • Revision ID: git-v1:d8c3500bae00a8a67d74f8f96235ec11d75231be
rename mozilla-minos-settings -> firefox-minos-settings

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ==UserScript==
 
2
// @name           LP_StockReplies
 
3
// @namespace      http://outflux.net/greasemonkey/
 
4
// @description    (Launchpad) Stock replies
 
5
// @include        https://launchpad.net/*
 
6
// @include        https://*.launchpad.net/*
 
7
// @include        https://*.edge.launchpad.net/*
 
8
// @version        1.5
 
9
// @date           2009-12-22
 
10
// @creator        Kees Cook <kees@ubuntu.com>
 
11
// @contributor    Brian Murray <brian@ubuntu.com>
 
12
// @contributor    Bryce Harrington <bryce@ubuntu.com>
 
13
// ==/UserScript==
 
14
// Based on code originally written by:
 
15
//  Tollef Fog Heen <tfheen@err.no>
 
16
//  Brian Murray <brian@ubuntu.com>
 
17
 
 
18
(function () {
 
19
  var SCRIPT = {
 
20
    name: "LP_StockReplies",
 
21
    namespace: "http://outflux.net/greasemonkey/",
 
22
    description: '(Launchpad) Stock replies',
 
23
    source: "http://codebrowse.launchpad.net/~ubuntu-dev/ubuntu-gm-scripts/ubuntu/files",
 
24
    identifier: "http://codebrowse.launchpad.net/~ubuntu-dev/ubuntu-gm-scripts/ubuntu/file/lp_stockreplies.user.js",
 
25
    version: "1.5",
 
26
    date: (new Date(2009, 12 - 1, 22))// update date
 
27
    .valueOf()
 
28
  };
 
29
 
 
30
function xpath(query, context) {
 
31
  context = context ? context : document;
 
32
  return document.evaluate(query, context, null,
 
33
                           XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
 
34
}
 
35
 
 
36
String.prototype.ucFirst = function () {
 
37
    return this.substr(0,1).toUpperCase() + this.substr(1,this.length);
 
38
};
 
39
 
 
40
var debug = 0;
 
41
 
 
42
var prefsData = new Object;
 
43
var prefsFields = new Array(
 
44
                            "name",       // required -- the clickable name
 
45
                            "comment",    // required -- the stock reply!
 
46
                            "status",     // "" == leave unchanged
 
47
                            "tip",        // tooltip hint (optional)
 
48
                            "assign",     // "" == leave unchanged
 
49
                                          // "-me" == assign to self
 
50
                                          // "-nobody" == assign to nobody
 
51
                            "importance", // "" == leave unchanged
 
52
                            "package",    // "" == leave unchanged
 
53
                            "standard"    // "yes" == is from standard XML?
 
54
                           );
 
55
 
 
56
 
 
57
// This routine is called once per stock reply item at time of page loading
 
58
function injectStockreply(formname, idx) {
 
59
 
 
60
  var element = document.createElement('a');
 
61
  element.href = document.location + "#";
 
62
  var innerTextElement = document.createTextNode(prefsData['name'][idx]);
 
63
 
 
64
  // Default to using comment as tooltip, when tooltip is missing
 
65
  tip = prefsData['tip'][idx];
 
66
  if (tip == "") {
 
67
    tip = prefsData['comment'][idx];
 
68
  }
 
69
  element.title = tip;
 
70
 
 
71
  element.appendChild(innerTextElement);
 
72
  element.addEventListener('click', function(e) {
 
73
    e.preventDefault();
 
74
 
 
75
    // Retrieve bug details
 
76
    var pathname = window.location.pathname;
 
77
    var bug_project = pathname.split('/')[1].ucFirst();
 
78
    // if the bug has no package this ends up being the bug number
 
79
    var bug_package = pathname.split('/')[3];
 
80
    var bug_number = pathname.split('/').pop();
 
81
    var bug_reporter = xpath("//*[@class='registering']/*[contains(@class,'sprite person')]").snapshotItem(0).firstChild.nodeValue;
 
82
    var bug_upstream = xpath("//*[@class='link-external']").snapshotItem(0);
 
83
 
 
84
    // Set comment
 
85
    var comment_text = prefsData['comment'][idx];
 
86
    comment_text = comment_text.replace("PROJECTNAME", bug_project);
 
87
    comment_text = comment_text.replace("BUGNUMBER", bug_number);
 
88
    // only replace the package name for bugs with a package i.e. don't do it for no package bugs
 
89
    if (bug_number != bug_package) {
 
90
        comment_text = comment_text.replace("PKGNAME", bug_package);
 
91
    }
 
92
    comment_text = comment_text.replace("REPORTER", bug_reporter);
 
93
    if (bug_upstream != null) {
 
94
        comment_text = comment_text.replace("UPSTREAMBUG", bug_upstream.href);
 
95
    }
 
96
    xpath('//textarea[@id="'+  formname + '.comment_on_change"]').snapshotItem(0).value = comment_text;
 
97
 
 
98
    // Set status
 
99
    if (prefsData['status'][idx] != "") {
 
100
        xpath('//select[@id="'+  formname + '.status"]/option[.="'+prefsData['status'][idx].replace(/"/,'\\"')+'"]').snapshotItem(0).selected = true;
 
101
    }
 
102
 
 
103
    // Set assignee
 
104
    if (prefsData['assign'][idx] != "") {
 
105
        if (prefsData['assign'][idx] == "-me") {
 
106
            xpath('//input[@value="'+ formname + '.assignee.assign_to_me"]').snapshotItem(0).checked = true;
 
107
        }
 
108
        else if (prefsData['assign'][idx] == "-nobody") {
 
109
            xpath('//input[@value="'+ formname + '.assignee.assign_to_nobody"]').snapshotItem(0).checked = true;
 
110
        }
 
111
        else {
 
112
            xpath('//input[@value="'+ formname + '.assignee.assign_to"]').snapshotItem(0).checked = true;
 
113
            xpath('//input[@id="'+  formname + '.assignee"]').snapshotItem(0).value = prefsData['assign'][idx];
 
114
        }
 
115
    }
 
116
 
 
117
    // Set package
 
118
    if (prefsData['package'][idx] != "") {
 
119
        xpath('//input[@name="'+  formname + '.target.package"]').snapshotItem(0).value = prefsData['package'][idx];
 
120
    }
 
121
 
 
122
    // Set importance
 
123
    if (prefsData['importance'][idx] != "") {
 
124
        xpath('//select[@id="'+  formname + '.importance"]/option[.="'+prefsData['importance'][idx].replace(/"/,'\\"')+'"]').snapshotItem(0).selected = true;
 
125
    }
 
126
 
 
127
    // Subscribe triager by default
 
128
//    var sub = xpath('//input[@id="subscribe"]').snapshotItem(0);
 
129
//    if (sub) sub.checked = true;
 
130
 
 
131
    return false;
 
132
  }, false);
 
133
  return element;
 
134
}
 
135
 
 
136
var reply_class = 'lp_sr';
 
137
function insert_clickable(node, newElement, tagged, left, right)
 
138
{
 
139
    if (!left)  { left='['; }
 
140
    if (!right) { right=']'; }
 
141
    var span = document.createElement("span");
 
142
    var leftBrace = document.createTextNode(left);
 
143
    var rightBrace = document.createTextNode(right+' ');
 
144
 
 
145
    /* mark up for future removal? */
 
146
    if (tagged) {
 
147
        span.setAttribute('class',reply_class)
 
148
    }
 
149
 
 
150
    /* fill span */
 
151
    span.appendChild(leftBrace);
 
152
    span.appendChild(newElement);
 
153
    span.appendChild(rightBrace);
 
154
    // make the source readable
 
155
    span.appendChild(document.createTextNode("\n"));
 
156
 
 
157
    /* insert span */
 
158
    node.insertBefore(span, span.nextSibling);
 
159
}
 
160
 
 
161
function deleteReply(idx)
 
162
{
 
163
    var count = parseInt(GM_getValue('count',0))
 
164
    if (count == 0) return;
 
165
    if (idx >= count) return;
 
166
    if (idx < 0) return;
 
167
    /* move all the prefs up one to wipe out the deleted one */
 
168
    for (var move = idx + 1; move < count; move ++) {
 
169
        for (var field in prefsFields) {
 
170
            for (var field in prefsFields) {
 
171
                var fieldname = prefsFields[field];
 
172
                GM_setValue(fieldname+(move-1),GM_getValue(fieldname+move,""));
 
173
            }
 
174
        }
 
175
    }
 
176
    GM_setValue('count',''+(count-1))
 
177
    /* since we've deleted a reply, caller needs to reload this script's
 
178
       view of the GM prefs via loadPreferences() */
 
179
}
 
180
 
 
181
function clearStandardReplies()
 
182
{
 
183
    var count = parseInt(GM_getValue('count', 0));
 
184
    for (var idx = count - 1; idx >= 0; idx --) {
 
185
        standard = GM_getValue('standard'+idx,"");
 
186
        if (standard == "yes") {
 
187
            deleteReply(idx, false);
 
188
        }
 
189
    }
 
190
    loadPreferences();
 
191
}
 
192
 
 
193
function loadPreferences()
 
194
{
 
195
    prefsData.standardSeen = false;
 
196
    prefsData.count = parseInt(GM_getValue('count', 0));
 
197
    for (var field in prefsFields) {
 
198
        var fieldname = prefsFields[field];
 
199
        prefsData[fieldname] = new Array;
 
200
 
 
201
        for (var idx = 0; idx < prefsData.count; idx ++) {
 
202
            prefsData[fieldname][idx] = GM_getValue(fieldname+idx,"");
 
203
        }
 
204
    }
 
205
    for (var idx = 0; idx < prefsData.count; idx ++) {
 
206
        if (prefsData['standard'][idx] == "yes") {
 
207
            prefsData.standardSeen = true;
 
208
        }
 
209
    }
 
210
    prefsData.reloadAt = parseInt(GM_getValue('reload-at', 0));
 
211
}
 
212
 
 
213
function loadStandardReplies() {
 
214
    GM_xmlhttpRequest
 
215
        (
 
216
          {
 
217
            method: 'GET',
 
218
            url:    'http://people.ubuntu.com/~brian/greasemonkey/bugsquad-replies.xml',
 
219
            headers: {
 
220
                'Accept': 'application/atom+xml,application/xml,text/xml',
 
221
            },
 
222
            onload:  function(results) {
 
223
                var parser = new DOMParser();
 
224
                var dom = parser.parseFromString(results.responseText,"application/xml");
 
225
                var replies = dom.getElementsByTagName('reply');
 
226
                // destroy preferences for possible reload
 
227
                hidePreferences();
 
228
                /* if we actually have some replies, clear the old ones */
 
229
                if (debug) {
 
230
                    alert("Dropping old standard stock replies");
 
231
                }
 
232
                if (replies.length>0) {
 
233
                    clearStandardReplies();
 
234
                }
 
235
                if (debug) {
 
236
                    alert("Parsing new standard stock replies");
 
237
                }
 
238
                var base = prefsData.count;
 
239
                for (var i=0; i < replies.length; i++) {
 
240
                    var standardReply = new Array;
 
241
                    for (var field in prefsFields) {
 
242
                        var fieldname = prefsFields[field];
 
243
                        var text = "";
 
244
                        if (fieldname == "standard") {
 
245
                            text = "yes";
 
246
                        }
 
247
                        else {
 
248
                            // alert("Want " + fieldname + " (offset " + i + ")");
 
249
                            element = replies[i].getElementsByTagName(fieldname);
 
250
                            if (element.length) {
 
251
                                text = element[0].textContent;
 
252
                            }
 
253
                        }
 
254
                        prefsData[fieldname][base+i] = text;
 
255
                        // alert(fieldname + " as [" + text + "] at " + (base+i));
 
256
                        if (debug) {
 
257
                            if (fieldname == "name") {
 
258
                                alert("Parsed [" + text + "]");
 
259
                            }
 
260
                        }
 
261
                    }
 
262
                }
 
263
                prefsData.count += replies.length;
 
264
                // reload again in 1.5 days
 
265
                var time = new Date();
 
266
                prefsData.reloadAt = time.getUTCMilliseconds() + (1000 * 60 * 60 * 36);
 
267
                if (debug) {
 
268
                    alert("Saving stock replies");
 
269
                }
 
270
                savePreferences();
 
271
                if (debug) {
 
272
                    alert("Finished reloading standard stock replies");
 
273
                }
 
274
            }
 
275
          }
 
276
        )
 
277
}
 
278
 
 
279
function addColumnPreference(idx,fieldname)
 
280
{
 
281
        var td = document.createElement('td');
 
282
        // why doesn't this alignment work?
 
283
        //td.setAttribute('valign','top');
 
284
 
 
285
        var id = reply_class + '.' + idx + '.' + fieldname;
 
286
 
 
287
        var label = document.createElement('label');
 
288
        label.setAttribute('style','font-weight: bold;');
 
289
        label.setAttribute('for',id);
 
290
        label.appendChild(document.createTextNode(fieldname));
 
291
        td.appendChild(label);
 
292
 
 
293
        var input;
 
294
        if (fieldname == 'comment') {
 
295
            input = document.createElement('textarea');
 
296
            // match current LP comment field size
 
297
            input.setAttribute('cols','62');
 
298
            input.setAttribute('rows','4');
 
299
        }
 
300
        else {
 
301
            input = document.createElement('input');
 
302
            input.setAttribute('type','text');
 
303
            input.setAttribute('size','15');
 
304
        }
 
305
        input.value = prefsData[fieldname][idx];
 
306
        input.setAttribute('name',fieldname);
 
307
        input.setAttribute('id',id);
 
308
        //alert('added ('+fieldname+','+idx+'): '+input.value);
 
309
        input.addEventListener('change', function(e) {
 
310
                e.preventDefault();
 
311
 
 
312
                var obj = e.target;
 
313
                var fieldname = obj.getAttribute('name');
 
314
                //alert('changed ('+fieldname+','+idx+'): '+obj.value);
 
315
                if (prefsData[fieldname][idx] != obj.value) {
 
316
                    /* mark as non-standard if it was changed */
 
317
                    prefsData['standard'][idx] = "";
 
318
                }
 
319
                prefsData[fieldname][idx] = obj.value;
 
320
 
 
321
                return false;
 
322
            }, false);
 
323
        td.appendChild(input);
 
324
 
 
325
        // make the source readable
 
326
        td.appendChild(document.createTextNode("\n"));
 
327
 
 
328
    return td;
 
329
}
 
330
 
 
331
function addRowPreferences(table,idx)
 
332
{
 
333
    /* TODO: mark this row in some way if it is a standard reply */
 
334
    var tr = document.createElement('tr');
 
335
    for (var field in prefsFields) {
 
336
        var fieldname = prefsFields[field];
 
337
        if (fieldname == 'standard') continue;
 
338
        if (fieldname == 'comment') continue;
 
339
 
 
340
        // set up empty default
 
341
        if (!prefsData[fieldname][idx]) {
 
342
            prefsData[fieldname][idx]="";
 
343
        }
 
344
 
 
345
        td = addColumnPreference(idx,fieldname);
 
346
        tr.appendChild(td);
 
347
    }
 
348
    table.appendChild(tr);
 
349
 
 
350
    // make the source readable
 
351
    table.appendChild(document.createTextNode("\n"));
 
352
 
 
353
    // add "comment" input separately since it is a textarea
 
354
    var comment_tr = document.createElement('tr');
 
355
    var comment_td = addColumnPreference(idx,'comment');
 
356
    comment_td.setAttribute('colspan', prefsFields.length - 2);
 
357
    comment_tr.appendChild( comment_td );
 
358
    table.appendChild(comment_tr);
 
359
 
 
360
    // make the source readable
 
361
    table.appendChild(document.createTextNode("\n"));
 
362
 
 
363
    // spacer
 
364
    var sep_td = document.createElement('td');
 
365
    var sep_tr = document.createElement('tr');
 
366
    sep_td.appendChild(document.createTextNode("\u00A0")); // nbsp
 
367
    sep_tr.appendChild( sep_td );
 
368
    table.appendChild( sep_tr );
 
369
 
 
370
    // did we bump the count higher?
 
371
    if (prefsData.count == idx) {
 
372
        prefsData.count++;
 
373
    }
 
374
}
 
375
 
 
376
function showPreferences(prefsDiv)
 
377
{
 
378
    var tr;
 
379
    var table = document.createElement('table');
 
380
    prefsDiv.appendChild(table);
 
381
 
 
382
    // get the count and initialize arrays
 
383
    var count = prefsData.count;
 
384
 
 
385
/*
 
386
    // table headers
 
387
    tr = document.createElement('tr');
 
388
    table.appendChild(tr);
 
389
 
 
390
    for (var field in prefsFields) {
 
391
        var fieldname = prefsFields[field];
 
392
        if (fieldname == 'standard') continue;
 
393
        if (fieldname == 'comment') continue;
 
394
 
 
395
        var th = document.createElement('th');
 
396
        // why doesn't this alignment work?
 
397
        //th.setAttribute('align','left');
 
398
        th.appendChild(document.createTextNode(fieldname));
 
399
        tr.appendChild(th);
 
400
    }
 
401
*/
 
402
 
 
403
    // load the preferences
 
404
    var reload_time_seen = false;
 
405
    for (var idx = 0; idx < count; idx ++) {
 
406
 
 
407
        if (prefsData['standard'][idx] == 'yes' && !reload_time_seen) {
 
408
            var time = new Date();
 
409
            time.setUTCMilliseconds( prefsData.reloadAt );
 
410
 
 
411
            var sep_tr;
 
412
            var sep_td;
 
413
 
 
414
            // spacer
 
415
            sep_td = document.createElement('td');
 
416
            sep_tr = document.createElement('tr');
 
417
            sep_td.appendChild(document.createTextNode("\u00A0")); // nbsp
 
418
            sep_tr.appendChild( sep_td );
 
419
            table.appendChild( sep_tr );
 
420
 
 
421
            // report auto-reload time
 
422
            sep_tr = document.createElement('tr');
 
423
            sep_td = document.createElement('td');
 
424
            var sep_span = document.createElement('span');
 
425
            sep_td.setAttribute('colspan', prefsFields.length - 2);
 
426
            sep_span.appendChild(document.createTextNode("Standard Replies (next auto-reload at: "+ time.toString() +")"));
 
427
            sep_span.setAttribute('style','font-weight: bold;');
 
428
            sep_td.appendChild( sep_span );
 
429
            sep_tr.appendChild( sep_td );
 
430
            table.appendChild( sep_tr );
 
431
 
 
432
            // spacer
 
433
            sep_td = document.createElement('td');
 
434
            sep_tr = document.createElement('tr');
 
435
            sep_td.appendChild(document.createTextNode("\u00A0")); // nbsp
 
436
            sep_tr.appendChild( sep_td );
 
437
            table.appendChild( sep_tr );
 
438
 
 
439
            reload_time_seen = true;
 
440
        }
 
441
 
 
442
        addRowPreferences(table, idx);
 
443
    }
 
444
 
 
445
    // Show pref-control buttons
 
446
    tr = document.createElement('tr');
 
447
    table.appendChild(tr);
 
448
 
 
449
    // Expand list
 
450
    var td = document.createElement('td');
 
451
    var click = document.createElement('a');
 
452
    click.href = document.location + "#";
 
453
    click.title = "Expand form with a new blank entry for stock replies (remember to click save!)";
 
454
    click.appendChild(document.createTextNode("Add New Stock Reply"));
 
455
    click.addEventListener('click', function(e) {
 
456
            e.preventDefault();
 
457
 
 
458
            addRowPreferences(table, prefsData.count);
 
459
 
 
460
            return false;
 
461
        }, false);
 
462
    insert_clickable(td, click, false);
 
463
    tr.appendChild(td);
 
464
 
 
465
    // Save preferences
 
466
    var td = document.createElement('td');
 
467
    var click = document.createElement('a');
 
468
    click.title = "Save the stock replies to disk (Important Note:  You will need to restart firefox for the replies to save permanently)";
 
469
    click.href = document.location + "#";
 
470
    click.appendChild(document.createTextNode("Save Stock Replies"));
 
471
    click.addEventListener('click', function(e) {
 
472
            e.preventDefault(); 
 
473
 
 
474
            savePreferences();
 
475
 
 
476
            alert('Replies Saved');
 
477
 
 
478
            return false;
 
479
        }, false);
 
480
    insert_clickable(td, click, false);
 
481
    tr.appendChild(td);
 
482
 
 
483
}
 
484
 
 
485
function savePreferences()
 
486
{
 
487
    // save the count
 
488
    GM_setValue('count', ''+prefsData.count);
 
489
    // save standard-reply-reload date
 
490
    GM_setValue('reload-at', ''+prefsData.reloadAt);
 
491
 
 
492
    // save the preferences
 
493
    for (var idx = 0; idx < prefsData.count; idx ++) {
 
494
        for (var field in prefsFields) {
 
495
            //alert("Saving "+prefsFields[field]+idx);
 
496
            GM_setValue(prefsFields[field]+idx, prefsData[prefsFields[field]][idx]);
 
497
        }
 
498
    }
 
499
 
 
500
    // redisplay the prefs!
 
501
    remove_replies();
 
502
    show_replies();
 
503
}
 
504
 
 
505
/*
 
506
function reloadReplies(title) {
 
507
    var element = document.createElement('a');
 
508
    element.href = document.location + "#";
 
509
    var innerTextElement = document.createTextNode(title);
 
510
    element.title = "Reload the replies from preferences";
 
511
    element.appendChild(innerTextElement);
 
512
    element.addEventListener('click', function(e) {
 
513
            e.preventDefault();
 
514
 
 
515
            remove_replies();
 
516
            show_replies();
 
517
 
 
518
            return false;
 
519
        }, false);
 
520
  return element;
 
521
}
 
522
*/
 
523
function reloadStandardReplies(title) {
 
524
    var element = document.createElement('a');
 
525
    element.href = document.location + "#";
 
526
    var innerTextElement = document.createTextNode(title);
 
527
    element.appendChild(innerTextElement);
 
528
    element.title = "Reload the standard replies from remote website";
 
529
    element.addEventListener('click', function(e) {
 
530
            e.preventDefault();
 
531
 
 
532
            loadStandardReplies();
 
533
            alert('Refreshing Standard Replies');
 
534
 
 
535
            return false;
 
536
        }, false);
 
537
  return element;
 
538
}
 
539
 
 
540
var prefsDiv = null;
 
541
var prefsId = 'lp_sr_prefs';
 
542
function hidePreferences() {
 
543
    var prefs = document.getElementById(prefsId);
 
544
    if (prefs) {
 
545
        prefs.parentNode.removeChild(prefs);
 
546
        prefsDiv = null;
 
547
    }
 
548
}
 
549
 
 
550
function popPreferences(title) {
 
551
    var element = document.createElement('a');
 
552
    element.href = document.location + "#";
 
553
    var innerTextElement = document.createTextNode(title);
 
554
    element.title = "Display the stock replies preferences form";
 
555
    element.appendChild(innerTextElement);
 
556
    element.addEventListener('click', function(e) {
 
557
            e.preventDefault();
 
558
 
 
559
            // create the dialog if it doesn't exist yet
 
560
            if (prefsDiv === null) {
 
561
                prefsDiv = document.createElement('div');
 
562
                prefsDiv.setAttribute('id',prefsId);
 
563
 
 
564
                showPreferences(prefsDiv);
 
565
            }
 
566
 
 
567
            // locate the prior dialog location
 
568
            var prefs = document.getElementById(prefsId);
 
569
            if (!prefs || (prefs.parentNode != element.parentNode)) {
 
570
                // if prefs already exists in the DOM, drop it from prior
 
571
                // location, so we can attach it to the current element.
 
572
                /* oh, this seems to happen automatically.  Thanks, DOM.
 
573
                if (prefs) {
 
574
                    prefs.parentNode.removeChild(prefs);
 
575
                }
 
576
                */
 
577
                element.parentNode.insertBefore(prefsDiv, prefsDiv.nextSibling);
 
578
            }
 
579
            else {
 
580
                prefs.parentNode.removeChild(prefs);
 
581
            }
 
582
 
 
583
            return false;
 
584
        }, false);
 
585
  return element;
 
586
}
 
587
 
 
588
function remove_replies() {
 
589
    var allReplies = xpath("//*[@class='"+reply_class+"']");
 
590
    for (var i = 0; i < allReplies.snapshotLength; i++) {
 
591
        var thisReply = allReplies.snapshotItem(i);
 
592
        thisReply.parentNode.removeChild(thisReply);
 
593
    }
 
594
}
 
595
 
 
596
function show_replies() {
 
597
  var allForms = xpath("//form");
 
598
  for (var i = 0; i < allForms.snapshotLength; i++) {
 
599
    var thisForm = allForms.snapshotItem(i);
 
600
    //var thisInput = xpath(".//input[contains(@name, '.sourcepackagename') or contains(@name, '.product')]", thisForm);
 
601
    var thisInput = xpath(".//input[contains(@name, '.target')]", thisForm);
 
602
    if (thisInput.snapshotLength == 0) {
 
603
        continue;
 
604
    }
 
605
    var formname = thisInput.snapshotItem(0).name;
 
606
    formname = formname.substr(0, formname.lastIndexOf("."));
 
607
    var thisSubmit = xpath(".//label[contains(@for, '.comment_on_change')]", thisForm).snapshotItem(0);
 
608
  
 
609
    // append all stock replies
 
610
    for (var idx = 0; idx < prefsData.count; idx++) {
 
611
        var left='{';
 
612
        var right='}';
 
613
        if (prefsData['standard'][idx] == "yes") {
 
614
            left='[';
 
615
            right=']';
 
616
        }
 
617
        insert_clickable(thisSubmit.parentNode,
 
618
                         injectStockreply(formname, idx), true, left, right);
 
619
    }
 
620
 
 
621
    // Add preferences "button"
 
622
    insert_clickable(thisSubmit.parentNode, popPreferences("+edit+"), true);
 
623
    //insert_clickable(thisSubmit.parentNode, reloadReplies("*"), true);
 
624
    insert_clickable(thisSubmit.parentNode, reloadStandardReplies("+reload+"), true);
 
625
 
 
626
  }
 
627
}
 
628
 
 
629
window.addEventListener("load", function(e) {
 
630
 
 
631
    loadPreferences();
 
632
    // load standard replies if none are already in the preferences, or
 
633
    // if the "reloadAt" preference has expired
 
634
    var time = new Date();
 
635
    if (!prefsData.standardSeen ||
 
636
        time.getUTCMilliseconds() > prefsData.reloadAt) {
 
637
        loadStandardReplies();
 
638
    }
 
639
 
 
640
    show_replies();
 
641
 
 
642
}, false);
 
643
 
 
644
})();