Merge lp:~gmb/launchpad/prince-of-ajax-dupefinding-bug-358510 into lp:launchpad

Proposed by Graham Binns
Status: Merged
Approved by: Graham Binns
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~gmb/launchpad/prince-of-ajax-dupefinding-bug-358510
Merge into: lp:launchpad
Diff against target: 477 lines (+247/-135)
3 files modified
lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js (+242/-133)
lib/canonical/launchpad/templates/launchpad-form.pt (+2/-1)
lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt (+3/-1)
To merge this branch: bzr merge lp:~gmb/launchpad/prince-of-ajax-dupefinding-bug-358510
Reviewer Review Type Date Requested Status
Michael Nelson (community) code js Approve
Canonical Launchpad Engineering code Pending
Review via email: mp+15273@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Graham Binns (gmb) wrote :

This branch lays the groundwork for making the +filebug dupefinder
asynchronous. The branch contains several JavaScript changes designed to
make async dupefinding work; once this branch lands a subsequent branch
will actually switch those changes on and hook them up as appropriate.

The contents of the branch have been reviewed before, but those branches
got far too out of date to be merged, so I'm resubmitting this for
review.

Here's a list of the changes I've made:

== lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js ==

 - I've added a couple of globals which will be used to hold references
   to the search field and search button on the +filebug form.
 - I've updated show_bug_reporting_form to cope with situations where
   there aren't any suggested dupes. I've also altered the function so
   that it's ready for the switch to async dupe finding, whereafter the
   filebug form will be loaded in a hidden container.
 - I've added a function, search_for_and_display_dupes(). This function
   takes care of the asynchronous dupefinding. It grabs the duplicate
   search URL from the +filebug page and uses it to make a GET request
   to Launchpad for the list of possible duplicates for a given bug
   title, then updates the page with that list. This function is
   currently dormant (see below).
 - I've added a function, set_up_dupe_finder, which will be called when
   the async dupe finder functionality is turned on and which sets up
   the dupe finder to work asynchronously.
 - I've moved the body of the old Y.bugs.setup_dupe_finder() into a
   function called Y.bugs.setup_dupes() (its previous name was something
   of a misnomer, really).
 - I've made Y.bugs.setup_dupe_finder() into a much smaller function,
   which will check for the ability to load duplicates asynchronously
   and then call set_up_dupe_finder() appropriately. Currently, this
   function isn't called anywhere, thus disabling the async dupe search.

== lib/canonical/launchpad/templates/launchpad-form.pt ==

 - I've added an 'id' attribute to the launchpad form macro, so that we
   can pass identifiers to forms to be able to better grab them with
   JavaScript.

== lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt ==

 - I've updated this template to call Y.bugs.setup_dupes() instead of
   .setup_dupe_finder()

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js
  lib/canonical/launchpad/templates/launchpad-form.pt
  lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt

== JSLint notices ==
jslint: No problem found in '/home/graham/canonical/lp-branches/prince-of-ajax-dupefinding-bug-358510/lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js'.

jslint: 1 file to lint.

Revision history for this message
Graham Binns (gmb) wrote :

A note on testing this:

Basically, we know this branch works if:

 1. None of the pagetests fail.
 2. The behaviour of the +filebug form is not altered in any way.

I.e., this branch lands code, but the code shouldn't change the way that Launchpad behaves. There's a bit of refactoring and some new functionality, but the new stuff isn't turned on yet.

Revision history for this message
Michael Nelson (michael.nelson) wrote :
Download full text (15.1 KiB)

Hi Graham,

Your code looks great - it'll be an excellent change when it lands - but
it's quite difficult to review it like this when I can't see what
it does, or test the functionality (as opposed to testing that non of
it is currently run).

Also, there are a few points below where you've still got work-in-progress
code - so I'm ok with approving this branch as long as you're not landing
it on its own like this, but rather as part of a subsequent branch
(just use the 'Prerequisite branch' option when you create the MP
via the UI, so that the next reviewer won't see all these changes.) As it really needs a review where the functionality can be observed and tested.

It would be great if this new functionality could be tested with some JS unit-tests in lib/canonical/launchpad/javascript/bugs/tests/ in a subsequent branch too.

Thanks for all the cleanups too!

> === modified file 'lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js'
> --- lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js 2009-11-23 19:29:02 +0000
> +++ lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js 2009-11-26 13:39:58 +0000
[...]
> @@ -99,6 +113,67 @@
> }
>
> /**
> + * Search for bugs that may match the text that the user has entered and
> + * display them in-line.
> + */
> +function search_for_and_display_dupes() {
> + function show_failure_message() {
> + Y.get('#possible-duplicates').set(INNER_HTML, 'FAIL');

erm, that's a temporary message right? I understood from your MP that
this branch doesn't enable the functionality, but are you planning to
hold off landing it until the subsequent branch is done?

There is a new error api in lazrjs which needs a little love, but will
be useful here soon.

> @@ -185,124 +260,160 @@
> }
>
>
> -Y.bugs.setup_dupe_finder = function() {
> - Y.on('domready', function() {
> - bug_already_reported_expanders = Y.all(
> - 'img.bug-already-reported-expander');
> - bug_reporting_form = Y.get('#bug_reporting_form');
> -
> - if (bug_already_reported_expanders !== null &&
> - bug_already_reported_expanders !== undefined) {
> -
> - // Set up the onclick handlers for the expanders.
> - Y.each(Y.all('.similar-bug'), function(row) {
> - var bug_details_div = row.query('div.duplicate-details');
> - var image = row.query('img.bug-already-reported-expander');
> - var bug_title_link = row.query('.duplicate-bug-link');
> - var view_bug_link = row.query('.view-bug-link');
> -
> - // Grab the initial height of the element and create a
> - // config for the slide_out animation. This allows us to
> - // deal with browsers like Opera in which the JS engine
> - // takes a punt at the right height for the slid-out
> - // drawer and gets it completely and utterly wrong.
> - var initial_height = bug_details_div.get('scrollHeight');
> - var slide_out_config = {
> - to: {
> - height: initial_height
> - }
> - };
...

review: Approve (code js)
Revision history for this message
Graham Binns (gmb) wrote :

Marking this as Approved for the sake of getting it off my to-do list.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js'
--- lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js 2009-11-24 09:30:01 +0000
+++ lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js 2009-12-08 11:01:17 +0000
@@ -12,6 +12,9 @@
12 DISPLAY = 'display',12 DISPLAY = 'display',
13 EXPANDER_COLLAPSED = '/@@/treeCollapsed',13 EXPANDER_COLLAPSED = '/@@/treeCollapsed',
14 EXPANDER_EXPANDED = '/@@/treeExpanded',14 EXPANDER_EXPANDED = '/@@/treeExpanded',
15 INLINE = 'inline',
16 INNER_HTML = 'innerHTML',
17 LAZR_CLOSED = 'lazr-closed',
15 NONE = 'none',18 NONE = 'none',
16 SRC = 'src';19 SRC = 'src';
1720
@@ -21,12 +24,14 @@
21 * The NodeList of possible duplicates.24 * The NodeList of possible duplicates.
22 */25 */
23var bug_already_reported_expanders;26var bug_already_reported_expanders;
2427/*
25/*28 * The search field on the +filebug form
26 * The div in which the bug reporting form resides.29 */
27 */30var search_field;
28var bug_reporting_form;31/*
2932 * The search button on the +filebug form
33 */
34var search_button;
30/*35/*
31 * The boilerplate elements for the do-you-want-to-subscribe36 * The boilerplate elements for the do-you-want-to-subscribe
32 * FormOverlay.37 * FormOverlay.
@@ -50,7 +55,7 @@
5055
51 // Check that the details_div actually exists and raise an error if56 // Check that the details_div actually exists and raise an error if
52 // we can't find it.57 // we can't find it.
53 if (details_div === null) {58 if (!Y.Lang.isValue(details_div)) {
54 Y.fail(59 Y.fail(
55 "Unable to find details div for expander " + expander.get('id'));60 "Unable to find details div for expander " + expander.get('id'));
56 } else {61 } else {
@@ -76,29 +81,99 @@
76 * @param e The Event triggering this function.81 * @param e The Event triggering this function.
77 */82 */
78function show_bug_reporting_form(e) {83function show_bug_reporting_form(e) {
79 // Collapse all the duplicate-details divs.84 if (Y.Lang.isValue(bug_already_reported_expanders)) {
80 bug_already_reported_expanders.each(function(expander) {85 // Collapse any duplicate-details divs.
81 collapse_bug_details(expander);86 Y.each(bug_already_reported_expanders, function(expander) {
82 });87 collapse_bug_details(expander);
88 });
89 }
90
91 // If the bug reporting form is in a hidden container, as it is on
92 // the AJAX dupe search, show it.
93 var filebug_form_container = Y.get('#filebug-form-container');
94 if (Y.Lang.isValue(filebug_form_container)) {
95 filebug_form_container.setStyle(DISPLAY, BLOCK);
96 }
8397
84 // Show the bug reporting form.98 // Show the bug reporting form.
99 var bug_reporting_form = Y.get('#bug_reporting_form');
85 bug_reporting_form.setStyle(DISPLAY, BLOCK);100 bug_reporting_form.setStyle(DISPLAY, BLOCK);
86 Y.one(Y.DOM.byId('field.actions.submit_bug')).focus();101
87 window.location.href = '#form-start';102 Y.get(Y.DOM.byId('field.actions.submit_bug')).focus();
88103
89 // Focus the relevant elements of the form based on104 // Focus the relevant elements of the form based on
90 // whether the package drop-down is displayed.105 // whether the package drop-down is displayed.
91 var bugtarget_package_btn = Y.one(106 var bugtarget_package_btn = Y.one(
92 Y.DOM.byId('field.bugtarget.option.package'));107 Y.DOM.byId('field.bugtarget.option.package'));
93 if (bugtarget_package_btn !== null &&108 if (Y.Lang.isValue(bugtarget_package_btn)) {
94 bugtarget_package_btn !== undefined) {109 Y.get(Y.DOM.byId('field.bugtarget.package')).focus();
95 Y.one(Y.DOM.byId('field.bugtarget.package')).focus();
96 } else {110 } else {
97 Y.one(Y.DOM.byId('field.comment')).focus();111 Y.one(Y.DOM.byId('field.comment')).focus();
98 }112 }
99}113}
100114
101/**115/**
116 * Search for bugs that may match the text that the user has entered and
117 * display them in-line.
118 */
119function search_for_and_display_dupes() {
120 function show_failure_message() {
121 Y.get('#possible-duplicates').set(INNER_HTML, 'FAIL');
122 }
123
124 function on_success(transaction_id, response, args) {
125 // Hide the spinner and show the duplicates.
126 Y.get('#spinner').setStyle(DISPLAY, NONE);
127
128 var duplicate_div = Y.get('#possible-duplicates');
129 duplicate_div.set(INNER_HTML, response.responseText);
130
131 bug_already_reported_expanders = Y.all(
132 'img.bug-already-reported-expander');
133 if (Y.Lang.isValue(bug_already_reported_expanders)) {
134 // If there are duplicates shown, change the title of the page
135 // and set up the JavaScript of the duplicates that have been
136 // returned.
137 Y.bugs.setup_dupes();
138 Y.get('#page-title').set(
139 INNER_HTML,
140 'Is the bug you’re reporting one of these?');
141 } else {
142 // Otherwise, set the title to one that doesn't suggest
143 // there were dupes returned and show the bug reporting
144 // form.
145 Y.get('#page-title').set(INNER_HTML, 'Report a bug');
146 show_bug_reporting_form();
147 }
148
149 // Copy the value from the search field into the title field
150 // on the filebug form.
151 Y.get(Y.DOM.byId('field.title')).set(
152 'value', search_field.get('value'));
153
154 // Finally, change the label on the search button and show it
155 // again.
156 search_button.set('value', 'Check again');
157 search_button.setStyle(DISPLAY, INLINE);
158 }
159
160 var search_term = encodeURI(search_field.get('value'));
161 var search_url_base = Y.get(
162 '#duplicate-search-url').getAttribute('href');
163 var search_url = search_url_base + '?title=' + search_term;
164
165 // Hide the button, show the spinner and clear the contents of the
166 // possible duplicates div.
167 search_button.setStyle(DISPLAY, NONE);
168 Y.get('#spinner').setStyle(DISPLAY, INLINE);
169 Y.get('#possible-duplicates').set(INNER_HTML, '');
170
171 config = {on: {success: on_success,
172 failure: show_failure_message}};
173 Y.io(search_url, config);
174}
175
176/*
102 * Create the overlay for a user to optionally subscribe to a bug that177 * Create the overlay for a user to optionally subscribe to a bug that
103 * affects them.178 * affects them.
104 * @param form The form to which the FormOverlay is going to be179 * @param form The form to which the FormOverlay is going to be
@@ -108,10 +183,10 @@
108 // Grab the bug id and title from the "Yes, this is my bug" form.183 // Grab the bug id and title from the "Yes, this is my bug" form.
109 var bug_id = form.one(184 var bug_id = form.one(
110 'input.bug-already-reported-as').get('value');185 'input.bug-already-reported-as').get('value');
111 var bug_title = Y.one('#bug-' + bug_id + '-title').get('innerHTML');186 var bug_title = Y.get('#bug-' + bug_id + '-title').get(INNER_HTML);
112187
113 if (bug_title.length > 35) {188 if (bug_title.length > 35) {
114 // Truncate the bug title if it's more than 30 characters long.189 // Truncate the bug title if it's more than 35 characters long.
115 bug_title = bug_title.substring(0, 35) + '...';190 bug_title = bug_title.substring(0, 35) + '...';
116 }191 }
117192
@@ -161,11 +236,8 @@
161236
162 // Add an on-click handler to the radio buttons to ensure that their237 // Add an on-click handler to the radio buttons to ensure that their
163 // labels' styles are set correctly when they're selected.238 // labels' styles are set correctly when they're selected.
164 var radio_buttons = form.all('input.subscribe-option');239 var radio_buttons = form.queryAll('input.subscribe-option');
165 radio_buttons.on('click', function(e) {240 if (Y.Lang.isValue(radio_buttons)) {
166 // Loop over the radio buttons and set their parent
167 // div's font-weight depending on whether they're
168 // checked or not.
169 Y.each(radio_buttons, function(radio_button) {241 Y.each(radio_buttons, function(radio_button) {
170 var weight = radio_button.get('checked') ? 'bold' : 'normal';242 var weight = radio_button.get('checked') ? 'bold' : 'normal';
171 radio_button.get('parentNode').setStyle('fontWeight', weight);243 radio_button.get('parentNode').setStyle('fontWeight', weight);
@@ -176,121 +248,158 @@
176}248}
177249
178250
179Y.bugs.setup_dupe_finder = function() {251/**
180 Y.on('domready', function() {252 * Set up the dupe finder, overriding the default behaviour of the
181 bug_already_reported_expanders = Y.all(253 * +filebug search form.
182 'img.bug-already-reported-expander');254 */
183 bug_reporting_form = Y.one('#bug_reporting_form');255function set_up_dupe_finder(transaction_id, response, args) {
184256 var filebug_form_container = Y.get('#filebug-form-container');
185 if (bug_already_reported_expanders.size() !== 0) {257 filebug_form_container.set(INNER_HTML, response.responseText);
186258
187 // Set up the onclick handlers for the expanders.259 // Activate the extra options collapsible section on the bug
188 Y.all('.similar-bug').each(function(row) {260 // reporting form.
189 var bug_details_div = row.one('div.duplicate-details');261 var bug_reporting_form = Y.get('#bug_reporting_form');
190 var image = row.one('img.bug-already-reported-expander');262 if (Y.Lang.isValue(bug_reporting_form)) {
191 var bug_title_link = row.one('.duplicate-bug-link');263 activateCollapsibles();
192 var view_bug_link = row.one('.view-bug-link');264 }
193265
194 // Grab the initial height of the element and create a266 search_button = Y.get(Y.DOM.byId('field.actions.search'));
195 // config for the slide_out animation. This allows us to267
196 // deal with browsers like Opera in which the JS engine268 // Change the name and id of the search field so that it doesn't
197 // takes a punt at the right height for the slid-out269 // confuse the view when we submit a bug report.
198 // drawer and gets it completely and utterly wrong.270 search_field = Y.get(Y.DOM.byId('field.title'));
199 var initial_height = bug_details_div.get('scrollHeight');271 search_field.set('name', 'field.search');
200 var slide_out_config = {272 search_field.set('id', 'field.search');
201 to: {273
202 height: initial_height274 // Disable the form so that hitting "enter" in the Summary
203 }275 // field no longer sends us through to the next page.
204 };276 // Y.on('submit', function(e) { e.halt(); }, '#my-form')
205277
206 // Shut down the default action for the link and mark it278 // Update the label on the search button so that it no longer
207 // as a JS'd link. We do this as it's simpler than279 // says "Continue".
208 // trying to find all the bits of the row that we want280 search_button.set('value', 'Next');
209 // to make clickable.281 search_button.set('type', 'button');
210 bug_title_link.addClass('js-action');282
211 bug_title_link.on('click', function(e) {283 // Set up the handlers for the search button and the input
212 e.preventDefault();284 // field.
213 });285 search_button.on('click', search_for_and_display_dupes);
214286}
215 // The "view this bug" link shouldn't trigger the287
216 // collapsible, so we stop the event from propagating.288Y.bugs.setup_dupes = function() {
217 view_bug_link.on('click', function(e) {289 bug_already_reported_expanders = Y.all(
218 e.stopPropagation();290 'img.bug-already-reported-expander');
219 });291 bug_reporting_form = Y.get('#bug_reporting_form');
220292
221 // The same is true for the collapsible section. People293 if (Y.Lang.isValue(bug_already_reported_expanders)) {
222 // may want to copy and paste this, which involves294 // Collapse all the details divs, since we don't want them
223 // clicking, so we stop the onclick event from295 // expanded first up.
224 // propagating here, too.296 Y.each(Y.all('div.duplicate-details'), function(div) {
225 bug_details_div.on('click', function(e) {297 collapse_bug_details(div);
226 e.stopPropagation();298 });
227 });299
228300 // Set up the onclick handlers for the expanders.
229 // Set up the on focus handler for the link so that301 Y.each(Y.all('.similar-bug'), function(row) {
230 // tabbing will expand the different bugs.302 var bug_details_div = row.query('div.duplicate-details');
231 bug_title_link.on('focus', function(e) {303 var image = row.query('img.bug-already-reported-expander');
232 if (!bug_details_div.hasClass('lazr-opened')) {304 var bug_title_link = row.query('.duplicate-bug-link');
233 var anim = Y.lazr.effects.slide_out(305 var view_bug_link = row.query('.view-bug-link');
234 bug_details_div, slide_out_config);306
235 anim.run();307 // Shut down the default action for the link and mark it
236308 // as a JS'd link. We do this as it's simpler than
237 image.set(SRC, EXPANDER_EXPANDED);309 // trying to find all the bits of the row that we want
238310 // to make clickable.
239 // If the bug reporting form is shown, hide it.311 bug_title_link.addClass('js-action');
240 if (bug_reporting_form.getStyle(DISPLAY) == BLOCK) {312 bug_title_link.on('click', function(e) {
241 bug_reporting_form.setStyle(DISPLAY, NONE);313 e.preventDefault();
242 }314 });
243 }315
244 });316 // The "view this bug" link shouldn't trigger the
245317 // collapsible, so we stop the event from propagating.
246 row.on('click', function(e) {318 view_bug_link.on('click', function(e) {
247 if (bug_details_div.hasClass('lazr-opened')) {319 e.stopPropagation();
248 collapse_bug_details(image);320 });
249 } else {321
250 var anim = Y.lazr.effects.slide_out(322 // The same is true for the collapsible section. People
251 bug_details_div, slide_out_config);323 // may want to copy and paste this, which involves
252 anim.run();324 // clicking, so we stop the onclick event from
253325 // propagating here, too.
254 image.set(SRC, EXPANDER_EXPANDED);326 bug_details_div.on('click', function(e) {
255 }327 e.stopPropagation();
328 });
329
330 // Set up the on focus handler for the link so that
331 // tabbing will expand the different bugs.
332 bug_title_link.on('focus', function(e) {
333 if (!bug_details_div.hasClass('lazr-opened')) {
334 var anim = Y.lazr.effects.slide_out(bug_details_div);
335 anim.run();
336
337 image.set(SRC, EXPANDER_EXPANDED);
256338
257 // If the bug reporting form is shown, hide it.339 // If the bug reporting form is shown, hide it.
258 if (bug_reporting_form.getStyle(DISPLAY) == BLOCK) {340 if (bug_reporting_form.getStyle(DISPLAY) == BLOCK) {
259 bug_reporting_form.setStyle(DISPLAY, NONE);341 bug_reporting_form.setStyle(DISPLAY, NONE);
260 }342 }
261 });343 }
262 });344 });
263345
264 // Hide the bug reporting form.346 row.on('click', function(e) {
265 bug_reporting_form.setStyle(DISPLAY, NONE);347 if (bug_details_div.hasClass('lazr-opened')) {
266348 collapse_bug_details(image);
267 // Collapse all the details divs, since we don't want them349 } else {
268 // expanded first up.350 var anim = Y.lazr.effects.slide_out(bug_details_div);
269 Y.all('div.duplicate-details').each(function(div) {351 anim.run();
270 collapse_bug_details(div);352
271 });353 image.set(SRC, EXPANDER_EXPANDED);
272354 }
273 }355
274356 // If the bug reporting form is shown, hide it.
275 bug_not_reported_button = Y.one('#bug-not-already-reported');357 if (bug_reporting_form.getStyle(DISPLAY) == BLOCK) {
276 if (bug_not_reported_button !== null &&358 bug_reporting_form.setStyle(DISPLAY, NONE);
277 bug_not_reported_button !== undefined) {359 }
278 // The bug_not_reported_button won't show up if there aren't any360 });
279 // possible duplicates.361 });
280 bug_not_reported_button.on('click', show_bug_reporting_form);362
281 }363 // Hide the bug reporting form.
282364 bug_reporting_form.setStyle(DISPLAY, NONE);
283 // Attach the form overlay to the "Yes, this is my bug" forms.365 }
284 Y.all('form.this-is-my-bug-form').each(function(form) {366
285 var subscribe_form_overlay = create_subscribe_overlay(form);367 bug_not_reported_button = Y.get('#bug-not-already-reported');
286368 if (Y.Lang.isValue(bug_not_reported_button)) {
287 form.on('submit', function(e) {369 // The bug_not_reported_button won't show up if there aren't any
288 // We don't care about the original event, so stop it370 // possible duplicates.
289 // and show the form overlay that we just created.371 bug_not_reported_button.on('click', show_bug_reporting_form);
290 e.halt();372 }
291 subscribe_form_overlay.show();373
292 });374 // Attach the form overlay to the "Yes, this is my bug" forms.
293 });375 var this_is_my_bug_forms = Y.all('form.this-is-my-bug-form');
376 Y.each(this_is_my_bug_forms, function(form) {
377 var subscribe_form_overlay = create_subscribe_overlay(form);
378
379 form.on('submit', function(e) {
380 // We don't care about the original event, so stop it
381 // and show the form overlay that we just created.
382 e.halt();
383 subscribe_form_overlay.show();
384 });
385 });
386};
387
388Y.bugs.setup_dupe_finder = function() {
389 Y.on('domready', function() {
390 config = {on: {success: set_up_dupe_finder,
391 failure: function() {}}};
392
393 // Load the filebug form asynchronously. If this fails we
394 // degrade to the standard mode for bug filing, clicking through
395 // to the second part of the bug filing form.
396 var filebug_form_url_element = Y.get(
397 '#filebug-form-url');
398 if (Y.Lang.isValue(filebug_form_url_element)) {
399 var filebug_form_url = filebug_form_url_element.getAttribute(
400 'href');
401 Y.io(filebug_form_url, config);
402 }
294 });403 });
295};404};
296405
297406
=== modified file 'lib/canonical/launchpad/templates/launchpad-form.pt'
--- lib/canonical/launchpad/templates/launchpad-form.pt 2009-09-03 15:39:22 +0000
+++ lib/canonical/launchpad/templates/launchpad-form.pt 2009-12-08 11:01:17 +0000
@@ -8,7 +8,8 @@
8 <div metal:define-macro="form">8 <div metal:define-macro="form">
99
10 <form action="."10 <form action="."
11 tal:attributes="action view/action_url"11 tal:attributes="action view/action_url;
12 id launchpad_form_id|nothing;"
12 name="launchpadform"13 name="launchpadform"
13 method="post"14 method="post"
14 enctype="multipart/form-data"15 enctype="multipart/form-data"
1516
=== modified file 'lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt'
--- lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt 2009-12-03 18:33:22 +0000
+++ lib/lp/bugs/templates/bugtarget-filebug-submit-bug.pt 2009-12-08 11:01:17 +0000
@@ -15,7 +15,9 @@
15 tal:attributes="src string:${lp_js}/bugs/filebug-dupefinder.js"></script>15 tal:attributes="src string:${lp_js}/bugs/filebug-dupefinder.js"></script>
16 <script type="text/javascript">16 <script type="text/javascript">
17 LPS.use('base', 'node', 'oop', 'event', 'bugs.dupe_finder', function(Y) {17 LPS.use('base', 'node', 'oop', 'event', 'bugs.dupe_finder', function(Y) {
18 Y.bugs.setup_dupe_finder();18 Y.on('domready', function() {
19 Y.bugs.setup_dupes();
20 });
19 });21 });
20 </script>22 </script>
21 </metal:block>23 </metal:block>