Merge lp:~gmb/launchpad/subscriber-portlet-timeout-bug-393476 into lp:launchpad

Proposed by Graham Binns
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~gmb/launchpad/subscriber-portlet-timeout-bug-393476
Merge into: lp:launchpad
Diff against target: 521 lines (+191/-95)
11 files modified
lib/canonical/launchpad/javascript/bugs/bugtask-index.js (+71/-4)
lib/lp/bugs/browser/bugsubscription.py (+9/-2)
lib/lp/bugs/browser/configure.zcml (+6/-0)
lib/lp/bugs/browser/tests/bug-portlet-subscribers-content.txt (+1/-1)
lib/lp/bugs/stories/bug-privacy/05-set-bug-private-as-admin.txt (+6/-3)
lib/lp/bugs/stories/bugs/bug-add-subscriber.txt (+4/-2)
lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt (+35/-16)
lib/lp/bugs/templates/bug-portlet-dupe-subscribers-content.pt (+27/-0)
lib/lp/bugs/templates/bug-portlet-subscribers-content.pt (+8/-17)
lib/lp/bugs/templates/bug-portlet-subscribers.pt (+16/-46)
lib/lp/bugs/tests/bug.py (+8/-4)
To merge this branch: bzr merge lp:~gmb/launchpad/subscriber-portlet-timeout-bug-393476
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+14502@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Graham Binns (gmb) wrote :
Download full text (3.4 KiB)

This branch fixes bug 393476 (subscribers portlet times out) by loading
the subscribers from duplicates separately from the main set of
subscribers.

Most bugs have a relatively low number of direct subscribers, but a bug
with a large number of duplicates can have thousands of indirect ones.
Loading these indirect subscribers can sometimes time out because of the
large number of subscribers and because in order to display them we need
to iterate over the result set before rendering the page.

My solution is to load the subscribers from duplicates separately.
Whilst we could spend time optimising the query and the iterations over
the result set, there will come a point where, for bugs with large
numbers of indirect subscribers, there will simply be too many to
handle. In those cases it's important that we still render the list of
direct subscribers (because that's usually the most interesting list of
subscribers on a bug page) and, most importantly, that we set up the
subscribe and unsubscribe links properly (at the moment the timeout
causes the AJAX controls to never get set up).

== Changes ==

=== lib/canonical/launchpad/javascript/bugs/bugtask-index.js ===

 - I've added two functions here. load_subscribers_from_duplicates()
   does the asynchronous loading of subs from dupes and
   Y.bugs.load_subscribers_portlet() contains the subs portlet setup
   code that was previously inline in the portlet template.
 - load_subscribers_from_duplicates() is now called once the
   portletloaded event is fired, meaning that it only happens once the
   direct subscribers have been loaded and the links have been set up
   correctly.

=== lib/lp/bugs/browser/bugsubscription.py ===

 - I've refactored the existing BugPortletSubcribersContents view into
   two views: BugPortletSubcribersContents and
   BugPortletDuplicateSubcribersContents. The second deals with the
   subs from dupes list.
 - I've updated the methods used in these views to turn them into
   @properties, per the coding standards.

=== lib/lp/bugs/browser/configure.zcml ===

 - I've added an entry for the BugPortletDuplicateSubcribersContents
   view.

=== lib/lp/bugs/templates/bug-portlet-dupe-subscribers-content.pt ===

 - I've added this template that displays only the list of subscribers
   from duplicates.

=== lib/lp/bugs/templates/bug-portlet-subscribers-content.pt ===

 - I've updated the existing template to remove the subs from dupes
   code.

=== lib/lp/bugs/templates/bug-portlet-subscribers.pt ===

 - I've removed the inline JS that didn't need to be inline, fixing bug
   369874 as a drive-by.

== 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/bugtask-index.js
  lib/lp/bugs/browser/bugsubscription.py
  lib/lp/bugs/browser/configure.zcml
  lib/lp/bugs/templates/bug-portlet-dupe-subscribers-content.pt
  lib/lp/bugs/templates/bug-portlet-subscribers-content.pt
  lib/lp/bugs/templates/bug-portlet-subscribers.pt

== JSLint notices ==
jslint: No problem found in '/home/graham/canonical/lp-branches/subscriber-portlet-t...

Read more...

Revision history for this message
Abel Deuring (adeuring) wrote :

looks good

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/javascript/bugs/bugtask-index.js'
2--- lib/canonical/launchpad/javascript/bugs/bugtask-index.js 2009-11-03 14:41:35 +0000
3+++ lib/canonical/launchpad/javascript/bugs/bugtask-index.js 2009-11-08 11:19:16 +0000
4@@ -46,15 +46,13 @@
5 * depends on that portlet being loaded, setup a custom
6 * event object, to provide a hook for initializing subscription
7 * link callbacks after a bugs:portletloaded event.
8- *
9- * XXX deryck 2009-04-30 bug=369874 Now this object exists,
10- * the inline js on bug-portlet-subscribers.pt should be moved here.
11-*/
12+ */
13 var PortletTarget = function() {};
14 Y.augment(PortletTarget, Y.Event.Target);
15 Y.bugs.portlet = new PortletTarget();
16 Y.bugs.portlet.subscribe('bugs:portletloaded', function() {
17 setup_subscription_link_handlers();
18+ load_subscribers_from_duplicates();
19 });
20 /*
21 * If the subscribers portlet fails to load, clear any
22@@ -1719,6 +1717,75 @@
23 });
24 }
25
26+function load_subscribers_from_duplicates() {
27+ if (Y.UA.ie) {
28+ return null;
29+ }
30+
31+ Y.get('#subscribers-portlet-dupe-spinner').setStyle(
32+ 'display', 'block');
33+
34+ function hide_spinner() {
35+ Y.get('#subscribers-portlet-dupe-spinner').setStyle(
36+ 'display', 'none');
37+ }
38+
39+ function on_success(transactionid, response, args) {
40+ hide_spinner();
41+
42+ var dupe_subscribers_container = Y.get(
43+ '#subscribers-from-duplicates-container');
44+ dupe_subscribers_container.set(
45+ 'innerHTML',
46+ dupe_subscribers_container.get('innerHTML') +
47+ response.responseText);
48+ }
49+
50+ var config = {on: {success: on_success,
51+ failure: hide_spinner}};
52+ var url = Y.get(
53+ '#subscribers-from-dupes-content-link').getAttribute(
54+ 'href').replace('bugs.', '');
55+ Y.io(url, config);
56+}
57+
58+Y.bugs.load_subscribers_portlet = function(
59+ subscription_link, subscription_link_handler) {
60+ if (Y.UA.ie) {
61+ return null;
62+ }
63+
64+ Y.get('#subscribers-portlet-spinner').setStyle('display', 'block');
65+
66+ function hide_spinner() {
67+ Y.get('#subscribers-portlet-spinner').setStyle('display', 'none');
68+ // Fire a custom event to notify that the initial click
69+ // handler on subscription_link set above should be
70+ // cleared.
71+ if (Y.bugs) {
72+ Y.bugs.portlet.fire(
73+ 'bugs:portletloadfailed', subscription_link_handler);
74+ }
75+ }
76+
77+ function on_success(transactionid, response, args) {
78+ hide_spinner();
79+ var portlet = Y.get('#portlet-subscribers');
80+ portlet.set('innerHTML',
81+ portlet.get('innerHTML') + response.responseText);
82+
83+ // Fire a custom portlet loaded event to notify when
84+ // it's safe to setup subscriber link callbacks.
85+ Y.bugs.portlet.fire('bugs:portletloaded');
86+ }
87+
88+ var config = {on: {success: on_success,
89+ failure: hide_spinner}};
90+ var url = Y.get(
91+ '#subscribers-content-link').getAttribute('href').replace('bugs.', '');
92+ Y.io(url, config);
93+};
94+
95 }, '0.1', {requires: ['base', 'oop', 'node', 'event', 'io-base', 'substitute',
96 'widget-position-ext', 'lazr.formoverlay', 'lazr.anim',
97 'lazr.base', 'lazr.overlay', 'lazr.choiceedit',
98
99=== modified file 'lib/lp/bugs/browser/bugsubscription.py'
100--- lib/lp/bugs/browser/bugsubscription.py 2009-08-31 15:41:15 +0000
101+++ lib/lp/bugs/browser/bugsubscription.py 2009-11-08 11:19:16 +0000
102@@ -5,6 +5,7 @@
103
104 __metaclass__ = type
105 __all__ = [
106+ 'BugPortletDuplicateSubcribersContents',
107 'BugPortletSubcribersContents',
108 'BugSubscriptionAddView',
109 ]
110@@ -61,7 +62,8 @@
111 class BugPortletSubcribersContents(LaunchpadView, BugViewMixin):
112 """View for the contents for the subscribers portlet."""
113
114- def getSortedDirectSubscriptions(self):
115+ @property
116+ def sorted_direct_subscriptions(self):
117 """Get the list of direct subscriptions to the bug.
118
119 The list is sorted such that subscriptions you can unsubscribe appear
120@@ -83,7 +85,12 @@
121 cannot_unsubscribe.append(subscription)
122 return can_unsubscribe + cannot_unsubscribe
123
124- def getSortedSubscriptionsFromDuplicates(self):
125+
126+class BugPortletDuplicateSubcribersContents(LaunchpadView, BugViewMixin):
127+ """View for the contents for the subscribers-from-dupes portlet block."""
128+
129+ @property
130+ def sorted_subscriptions_from_dupes(self):
131 """Get the list of subscriptions to duplicates of this bug."""
132 return [
133 SubscriptionAttrDecorator(subscription)
134
135=== modified file 'lib/lp/bugs/browser/configure.zcml'
136--- lib/lp/bugs/browser/configure.zcml 2009-10-30 12:09:16 +0000
137+++ lib/lp/bugs/browser/configure.zcml 2009-11-08 11:19:16 +0000
138@@ -998,6 +998,12 @@
139 class="lp.bugs.browser.bugsubscription.BugPortletSubcribersContents"
140 template="../templates/bug-portlet-subscribers-content.pt"
141 permission="zope.Public"/>
142+ <browser:page
143+ for="lp.bugs.interfaces.bug.IBug"
144+ name="+bug-portlet-dupe-subscribers-content"
145+ class="lp.bugs.browser.bugsubscription.BugPortletDuplicateSubcribersContents"
146+ template="../templates/bug-portlet-dupe-subscribers-content.pt"
147+ permission="zope.Public"/>
148 <browser:navigation
149 module="lp.bugs.browser.bug"
150 classes="
151
152=== modified file 'lib/lp/bugs/browser/tests/bug-portlet-subscribers-content.txt'
153--- lib/lp/bugs/browser/tests/bug-portlet-subscribers-content.txt 2009-06-12 16:36:02 +0000
154+++ lib/lp/bugs/browser/tests/bug-portlet-subscribers-content.txt 2009-11-08 11:19:16 +0000
155@@ -15,7 +15,7 @@
156 <BugSubscription at ...>
157 >>> bug.subscribe(view.user.teams_participated_in[0], view.user)
158 <BugSubscription at ...>
159- >>> for subscription in view.getSortedDirectSubscriptions():
160+ >>> for subscription in view.sorted_direct_subscriptions:
161 ... print '%s %s' % (
162 ... subscription.person.displayname,
163 ... subscription.canBeUnsubscribedByUser(view.user))
164
165=== modified file 'lib/lp/bugs/stories/bug-privacy/05-set-bug-private-as-admin.txt'
166--- lib/lp/bugs/stories/bug-privacy/05-set-bug-private-as-admin.txt 2009-06-12 16:36:02 +0000
167+++ lib/lp/bugs/stories/bug-privacy/05-set-bug-private-as-admin.txt 2009-11-08 11:19:16 +0000
168@@ -9,7 +9,8 @@
169 explicit. There are two implicit subscribers.
170
171 >>> from lp.bugs.tests.bug import (
172- ... print_direct_subscribers, print_indirect_subscribers)
173+ ... print_also_notified, print_direct_subscribers,
174+ ... print_subscribers_from_duplicates)
175
176 >>> browser.open(
177 ... "http://launchpad.dev/bugs/2/+bug-portlet-subscribers-content")
178@@ -17,8 +18,9 @@
179 >>> print_direct_subscribers(browser.contents)
180 Steve Alexander (Subscribed by Launchpad Janitor)
181
182- >>> print_indirect_subscribers(browser.contents)
183+ >>> print_subscribers_from_duplicates(browser.contents)
184 From duplicates:
185+ >>> print_also_notified(browser.contents)
186 Also notified:
187 Mark Shuttleworth
188 Sample Person
189@@ -46,8 +48,9 @@
190 Sample Person (Subscribed by Foo Bar)
191 Steve Alexander (Subscribed by Launchpad Janitor)
192
193- >>> print_indirect_subscribers(browser.contents)
194+ >>> print_subscribers_from_duplicates(browser.contents)
195 From duplicates:
196+ >>> print_also_notified(browser.contents)
197 Also notified:
198
199 When we go back to the secrecy form, the previously set value is pre-selected.
200
201=== modified file 'lib/lp/bugs/stories/bugs/bug-add-subscriber.txt'
202--- lib/lp/bugs/stories/bugs/bug-add-subscriber.txt 2009-09-18 15:24:30 +0000
203+++ lib/lp/bugs/stories/bugs/bug-add-subscriber.txt 2009-11-08 11:19:16 +0000
204@@ -32,7 +32,8 @@
205 currently subscribed to the bug:
206
207 >>> from lp.bugs.tests.bug import (
208- ... print_direct_subscribers, print_indirect_subscribers)
209+ ... print_also_notified, print_direct_subscribers,
210+ ... print_subscribers_from_duplicates)
211
212 >>> user_browser.open(
213 ... 'http://bugs.launchpad.dev/bugs/1/'
214@@ -40,8 +41,9 @@
215 >>> print_direct_subscribers(user_browser.contents)
216 Sample Person (Subscribed by Launchpad Janitor)
217 Steve Alexander (Subscribed by Launchpad Janitor)
218- >>> print_indirect_subscribers(user_browser.contents)
219+ >>> print_subscribers_from_duplicates(user_browser.contents)
220 From duplicates:
221+ >>> print_also_notified(user_browser.contents)
222 Also notified:
223 Foo Bar
224 Mark Shuttleworth
225
226=== modified file 'lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt'
227--- lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt 2009-09-19 10:04:20 +0000
228+++ lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt 2009-11-08 11:19:16 +0000
229@@ -4,7 +4,8 @@
230 in the actions portlet.
231
232 >>> from lp.bugs.tests.bug import (
233- ... print_direct_subscribers, print_indirect_subscribers)
234+ ... print_direct_subscribers, print_also_notified,
235+ ... print_subscribers_from_duplicates)
236
237 >>> browser = setupBrowser(auth='Basic foo.bar@canonical.com:test')
238 >>> browser.open('http://bugs.launchpad.dev/firefox/+bug/1')
239@@ -183,9 +184,13 @@
240 >>> stevea_browser = setupBrowser(
241 ... auth="Basic steve.alexander@ubuntulinux.com:test")
242 >>> stevea_browser.open(
243+ ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content")
244+ >>> print_subscribers_from_duplicates(stevea_browser.contents)
245+ From duplicates:
246+
247+ >>> stevea_browser.open(
248 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
249- >>> print_indirect_subscribers(stevea_browser.contents)
250- From duplicates:
251+ >>> print_also_notified(stevea_browser.contents)
252 Also notified:
253 Mark Shuttleworth
254
255@@ -200,14 +205,11 @@
256 >>> stevea_browser.getControl("Change").click()
257
258 >>> stevea_browser.open(
259- ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
260-
261- >>> print_indirect_subscribers(stevea_browser.contents)
262+ ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content")
263+ >>> print_subscribers_from_duplicates(stevea_browser.contents)
264 From duplicates:
265 Steve Alexander (Subscribed by Launchpad Janitor)
266 (Unsubscribe Steve Alexander)
267- Also notified:
268- Mark Shuttleworth
269
270 >>> stevea_browser.getLink(id='unsubscribe-subscriber-11').mech_link.url
271 '+subscribe'
272@@ -233,9 +235,13 @@
273 to bug #3.)
274
275 >>> stevea_browser.open(
276+ ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content")
277+ >>> print_subscribers_from_duplicates(stevea_browser.contents)
278+ From duplicates:
279+
280+ >>> stevea_browser.open(
281 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
282- >>> print_indirect_subscribers(stevea_browser.contents)
283- From duplicates:
284+ >>> print_also_notified(stevea_browser.contents)
285 Also notified:
286 Mark Shuttleworth
287
288@@ -256,12 +262,16 @@
289 >>> stevea_browser.getControl("Continue").click()
290
291 >>> stevea_browser.open(
292- ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
293- >>> print_indirect_subscribers(stevea_browser.contents)
294+ ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content")
295+ >>> print_subscribers_from_duplicates(stevea_browser.contents)
296 From duplicates:
297 Sample Person (Subscribed ...)
298 Steve Alexander (Subscribed ...) (Unsubscribe Steve Alexander)
299 testing Spanish team (Subscribed by Foo Bar)
300+
301+ >>> stevea_browser.open(
302+ ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
303+ >>> print_also_notified(stevea_browser.contents)
304 Also notified:
305 Mark Shuttleworth
306
307@@ -295,11 +305,16 @@
308 >>> foobar_browser.getControl("Subscribe user").click()
309
310 >>> foobar_browser.open(
311- ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
312+ ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content")
313
314- >>> print_indirect_subscribers(foobar_browser.contents)
315+ >>> print_subscribers_from_duplicates(foobar_browser.contents)
316 From duplicates:
317 Ubuntu Team (Subscribed by Foo Bar) (Unsubscribe Ubuntu Team)
318+
319+ >>> foobar_browser.open(
320+ ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
321+
322+ >>> print_also_notified(foobar_browser.contents)
323 Also notified:
324 Mark Shuttleworth
325
326@@ -326,9 +341,13 @@
327 (ubuntu-team is no longer an indirect subscriber.)
328
329 >>> foobar_browser.open(
330+ ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content")
331+ >>> print_subscribers_from_duplicates(foobar_browser.contents)
332+ From duplicates:
333+
334+ >>> foobar_browser.open(
335 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
336- >>> print_indirect_subscribers(foobar_browser.contents)
337- From duplicates:
338+ >>> print_also_notified(foobar_browser.contents)
339 Also notified:
340 Mark Shuttleworth
341
342
343=== added file 'lib/lp/bugs/templates/bug-portlet-dupe-subscribers-content.pt'
344--- lib/lp/bugs/templates/bug-portlet-dupe-subscribers-content.pt 1970-01-01 00:00:00 +0000
345+++ lib/lp/bugs/templates/bug-portlet-dupe-subscribers-content.pt 2009-11-08 11:19:16 +0000
346@@ -0,0 +1,27 @@
347+<div
348+ tal:omit-tag=""
349+ xmlns:tal="http://xml.zope.org/namespaces/tal"
350+ xmlns:metal="http://xml.zope.org/namespaces/metal"
351+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
352+ tal:define="
353+ bug context/bug|context;
354+ from_dupes_subscriptions view/sorted_subscriptions_from_dupes;
355+ ">
356+ <div
357+ tal:condition="from_dupes_subscriptions"
358+ id="subscribers-from-duplicates"
359+ class="section"
360+ >
361+ <h2>From duplicates</h2>
362+ <div
363+ tal:repeat="subscription from_dupes_subscriptions"
364+ tal:attributes="
365+ class subscription/css_name;
366+ id string:dupe-${subscription/css_name};
367+ "
368+ >
369+ <metal:subscriber
370+ metal:use-macro="bug/@@+bug-portlet-subscribers-content/subscriber-row" />
371+ </div>
372+ </div>
373+</div>
374
375=== modified file 'lib/lp/bugs/templates/bug-portlet-subscribers-content.pt'
376--- lib/lp/bugs/templates/bug-portlet-subscribers-content.pt 2009-08-03 12:53:22 +0000
377+++ lib/lp/bugs/templates/bug-portlet-subscribers-content.pt 2009-11-08 11:19:16 +0000
378@@ -5,8 +5,7 @@
379 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
380 tal:define="
381 bug context/bug|context;
382- direct_subscriptions view/getSortedDirectSubscriptions;
383- from_dupes_subscriptions view/getSortedSubscriptionsFromDuplicates;
384+ direct_subscriptions view/sorted_direct_subscriptions;
385 also_notified_subscribers bug/getAlsoNotifiedSubscribers
386 ">
387 <div class="section" id="subscribers-direct">
388@@ -17,7 +16,7 @@
389 tal:repeat="subscription direct_subscriptions"
390 tal:attributes="class subscription/css_name"
391 >
392- <metal:subscriber metal:define-macro="subscriber-row">
393+ <metal:subscriber metal:define-macro="subscriber-row">
394
395 <a
396 tal:condition="subscription/person/name|nothing"
397@@ -49,20 +48,12 @@
398 <div id="none-subscribers"
399 tal:condition="not:direct_subscriptions">None</div>
400 </div>
401- <div
402- tal:condition="from_dupes_subscriptions"
403- id="subscribers-from-duplicates"
404- class="section"
405- >
406- <h2>From duplicates</h2>
407- <div
408- tal:repeat="subscription from_dupes_subscriptions"
409- tal:attributes="
410- class subscription/css_name;
411- id string:dupe-${subscription/css_name};
412- "
413- >
414- <metal:subscriber metal:use-macro="template/macros/subscriber-row" />
415+ <div id="subscribers-from-duplicates-container">
416+ <a id="subscribers-from-dupes-content-link"
417+ tal:attributes="href bug/fmt:url/+bug-portlet-dupe-subscribers-content"></a>
418+ <div id="subscribers-portlet-dupe-spinner"
419+ style="text-align: center; display: none">
420+ <img src="/@@/spinner" />
421 </div>
422 </div>
423 <div
424
425=== modified file 'lib/lp/bugs/templates/bug-portlet-subscribers.pt'
426--- lib/lp/bugs/templates/bug-portlet-subscribers.pt 2009-10-29 21:39:12 +0000
427+++ lib/lp/bugs/templates/bug-portlet-subscribers.pt 2009-11-08 11:19:16 +0000
428@@ -23,52 +23,22 @@
429 </div>
430 <script type="text/javascript">
431 YUI().use('io-base', 'node', 'bugs.bugtask_index', function(Y) {
432- // Must be done inline here to ensure the load event fires.
433- // This is a work around for a YUI3 issue with event handling.
434- var subscription_link = Y.get('.menu-link-subscription');
435- var subscription_link_handler;
436- if (subscription_link) {
437- subscription_link_handler = subscription_link.on('click', function(e) {
438- e.preventDefault();
439- });
440- }
441- Y.on('domready', function() {
442- if (Y.UA.ie) {
443- return null;
444- }
445-
446- Y.get('#subscribers-portlet-spinner').setStyle('display', 'block');
447-
448- function hide_spinner() {
449- Y.get('#subscribers-portlet-spinner').setStyle('display', 'none');
450- // Fire a custom event to notify that the initial click handler
451- // on subscription_link set above should be cleared.
452- if (Y.bugs) {
453- Y.bugs.portlet.fire(
454- 'bugs:portletloadfailed', subscription_link_handler);
455- }
456- }
457-
458- function on_success(transactionid, response, arguments) {
459- hide_spinner();
460- var portlet = Y.get('#portlet-subscribers');
461- portlet.set('innerHTML',
462- portlet.get('innerHTML') + response.responseText);
463- // Fire a custom portlet loaded event to notify when
464- // it's safe to setup subscriber link callbacks.
465- // XXX deryck 2009-04-30 bug=369874 Now this object exists,
466- // the inline js here should be moved to bugtask-index.js.
467- // Moving will also prevent having the paranoia check for Y.bugs.
468- if (Y.bugs) {
469- Y.bugs.portlet.fire('bugs:portletloaded');
470- }
471- }
472-
473- var config = {on: {success: on_success,
474- failure: hide_spinner}};
475- var url = Y.get('#subscribers-content-link').getAttribute('href').replace('bugs.', '');
476- Y.io(url, config);
477- });
478+ // Must be done inline here to ensure the load event fires.
479+ // This is a work around for a YUI3 issue with event handling.
480+ var subscription_link = Y.get('.menu-link-subscription');
481+ var subscription_link_handler;
482+ if (subscription_link) {
483+ subscription_link_handler = subscription_link.on('click', function(e) {
484+ e.preventDefault();
485+ });
486+ }
487+
488+ Y.on('domready', function() {
489+ if (Y.bugs) {
490+ Y.bugs.load_subscribers_portlet(
491+ subscription_link, subscription_link_handler);
492+ }
493+ });
494 });
495 </script>
496 </div>
497
498=== modified file 'lib/lp/bugs/tests/bug.py'
499--- lib/lp/bugs/tests/bug.py 2009-08-18 11:04:38 +0000
500+++ lib/lp/bugs/tests/bug.py 2009-11-08 11:19:16 +0000
501@@ -33,12 +33,16 @@
502 print_subscribers(bug_page, 'subscribers-direct')
503
504
505-def print_indirect_subscribers(bug_page):
506- """Print the indirect subscribers listed in a portlet."""
507+def print_also_notified(bug_page):
508+ """Print the structural subscribers listed in a portlet."""
509+ print 'Also notified:'
510+ print_subscribers(bug_page, 'subscribers-indirect')
511+
512+
513+def print_subscribers_from_duplicates(bug_page):
514+ """Print the subscribers from duplicates listed in a portlet."""
515 print 'From duplicates:'
516 print_subscribers(bug_page, 'subscribers-from-duplicates')
517- print 'Also notified:'
518- print_subscribers(bug_page, 'subscribers-indirect')
519
520
521 def print_subscribers(bug_page, subscriber_list_id):