Merge lp:~sinzui/launchpad/progressive-enhancement-ftw-2 into lp:launchpad

Proposed by Curtis Hovey on 2012-04-28
Status: Merged
Approved by: j.c.sackett on 2012-04-30
Approved revision: no longer in the source branch.
Merged at revision: 15180
Proposed branch: lp:~sinzui/launchpad/progressive-enhancement-ftw-2
Merge into: lp:launchpad
Prerequisite: lp:~sinzui/launchpad/progressive-enhancement-ftw
Diff against target: 820 lines (+499/-92)
16 files modified
lib/lp/code/javascript/requestbuild_overlay.js (+15/-0)
lib/lp/code/javascript/tests/test_requestbuild_overlay.html (+16/-0)
lib/lp/code/javascript/tests/test_requestbuild_overlay.js (+55/-24)
lib/lp/code/javascript/tests/test_util.html (+85/-0)
lib/lp/code/javascript/tests/test_util.js (+90/-0)
lib/lp/code/javascript/util.js (+23/-9)
lib/lp/code/templates/branch-import-details.pt (+10/-11)
lib/lp/code/templates/branch-listing.pt (+1/-3)
lib/lp/code/templates/branchmergeproposal-generic-listing.pt (+5/-13)
lib/lp/code/templates/daily-builds-listing.pt (+1/-3)
lib/lp/code/templates/sourcepackagerecipe-index.pt (+7/-18)
lib/lp/translations/javascript/importqueue.js (+4/-0)
lib/lp/translations/javascript/tests/test_importqueue.html (+110/-0)
lib/lp/translations/javascript/tests/test_importqueue.js (+67/-0)
lib/lp/translations/templates/pofile-export.pt (+2/-1)
lib/lp/translations/templates/translation-import-queue-macros.pt (+8/-10)
To merge this branch: bzr merge lp:~sinzui/launchpad/progressive-enhancement-ftw-2
Reviewer Review Type Date Requested Status
j.c.sackett (community) 2012-04-28 Approve on 2012-04-30
Review via email: mp+103970@code.launchpad.net

Commit Message

Avoid noscript because it contradicts progressive enhancement assumptions.

Description of the Change

Pre-implementation: wgrant

Several features fail for less common browsers because noscript is used
for the default markup. When progressive enhancement fails, there is no
default markup to fallback to. YUI assumes progressive enhancement works.

Over the last 3 years, we have seen IE, Opera, Konquorer and Firefox 3
break because progressive enhancement failed without fallback.

The branch completes the removal of noscript by updating Code and
Translations.

--------------------------------------------------------------------

RULES

    * Remove all uses of noscript that interact with YUI.

QA

    # This page times out in production
    * Visit https://code.qastaging.launchpad.net/+daily-builds
    * Verify the js browser filters the branches when the select field
      is changed.
    * Verify the non-js browser shows the Filter button and submit it changes
      the listed branches.

    * Visit https://code.qastaging.launchpad.dev/pocket-lint/
    * Verify that the branch listing updates when the status and sort fields
      change in the js browser.
    * Verify the non-js browser shows the Filter button and submit it changes
      the listed branches.

    * https://code.qastaging.launchpad.net/pocket-lint/+merges
    * Verify that the branch listing updates when the status field
      changes in the js browser.
    * Verify the non-js browser shows the Filter button and submit it changes
      the listed branches.

    * Visit https://code.qastaging.launchpad.net/~vcs-imports/v8/trunk-svn
    * Verify the Retry button does not appear under Import details in
      the js browser; there is a retry link with a sprite.
    * Verify the Retry button appears under Import details the in
      non-js browser.

    * Visit https://code.qastaging.launchpad.net/~sinzui/+recipe/pocket-lint-daily
    * Verify the Build Now button does not appear under Build Schedule in
      the js browser.
    * Verify the Build Now button appears under Build Schedule in the
      non-js browser.

    * Visit https://translations.qastaging.launchpad.net/gdp/0.5.x/+pots/gedit-developer-plugins/es/+export
    * Verify the checkbox under format does not have the italic
      "PO format only:" text in the js browser.
    * Verify the italic text "PO format only:" appears below the checkbox
      in the non-js browser.

    * Visit https://translations.launchpad.net/+imports
    * Verify the statuses are choice links in the js-browser.
    * Verify the statuses are select widgets in the non-js browser and
      that there is a submit button below the listing.

LINT

    lib/lp/code/javascript/requestbuild_overlay.js
    lib/lp/code/javascript/tests/test_requestbuild_overlay.html
    lib/lp/code/javascript/tests/test_requestbuild_overlay.js
    lib/lp/code/javascript/tests/test_util.html
    lib/lp/code/javascript/tests/test_util.js
    lib/lp/code/javascript/util.js
    lib/lp/code/templates/branch-import-details.pt
    lib/lp/code/templates/branch-listing.pt
    lib/lp/code/templates/branchmergeproposal-generic-listing.pt
    lib/lp/code/templates/daily-builds-listing.pt
    lib/lp/code/templates/sourcepackagerecipe-index.pt
    lib/lp/translations/javascript/importqueue.js
    lib/lp/translations/templates/pofile-export.pt
    lib/lp/translations/templates/translation-import-queue-macros.pt
    lib/lp/translations/javascript/tests/test_importqueue.html
    lib/lp/translations/javascript/tests/test_importqueue.js

TEST

    ./bin/test -vvc --layer=YUITest lp.code
    ./bin/test -vvc --layer=YUITest lp.translations

IMPLEMENTATION

Added A new method to requestbuild_overlay to hide/show parts of the
build schedule when the page is setup. This was the only inline script
in the page...all the rest of the page was represented in the module
with tests. Adding a new testcase for my small change was frustrating, I
discovered that the existing tests were not cleaning up. I updated the
existing tests to tearDown to prevent duplicate ids from occurring. I
also simplified the setups to use a template.
    lib/lp/code/javascript/requestbuild_overlay.js
    lib/lp/code/javascript/tests/test_requestbuild_overlay.html
    lib/lp/code/javascript/tests/test_requestbuild_overlay.js
    lib/lp/code/templates/sourcepackagerecipe-index.pt

Replaced inline filter-listing-on-change behaviours with a module that
uses common code to support the common behaviour. I added a new YUI test
for all the methods that I changed to added.
    lib/lp/code/javascript/tests/test_util.html
    lib/lp/code/javascript/tests/test_util.js
    lib/lp/code/javascript/util.js
    lib/lp/code/templates/branch-import-details.pt
    lib/lp/code/templates/branch-listing.pt
    lib/lp/code/templates/branchmergeproposal-generic-listing.pt
    lib/lp/code/templates/daily-builds-listing.pt

I updated the page's inline script to hide the PO format only message. I
choose not to test this because the text does not offer functionality.
    lib/lp/translations/templates/pofile-export.pt

Updated Y.lp.translations.importqueue.initialize_import_queue_page() to
hide the html form selects and inputs that were hidden by noscript. I added
a YUI test. The html harness is huge :(
    lib/lp/translations/templates/translation-import-queue-macros.pt
    lib/lp/translations/javascript/importqueue.js
    lib/lp/translations/javascript/tests/test_importqueue.html
    lib/lp/translations/javascript/tests/test_importqueue.js

To post a comment you must log in.
j.c.sackett (jcsackett) wrote :

This looks good. Thanks for purging noscript and the improved test coverage.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/javascript/requestbuild_overlay.js'
2--- lib/lp/code/javascript/requestbuild_overlay.js 2012-03-14 12:53:47 +0000
3+++ lib/lp/code/javascript/requestbuild_overlay.js 2012-04-28 03:27:31 +0000
4@@ -48,6 +48,21 @@
5
6 namespace.RequestResponseHandler = RequestResponseHandler;
7
8+
9+namespace.hookUpDailyBuildsSchedule = function() {
10+ var logged_in = LP.links.me !== undefined;
11+ if (logged_in) {
12+ build_now_link = Y.one('#request-daily-build');
13+ if( build_now_link !== null ) {
14+ build_now_link.removeClass('unseen');
15+ Y.lp.code.requestbuild_overlay.connect_requestdailybuild();
16+ }
17+ Y.lp.code.requestbuild_overlay.connect_requestbuilds();
18+ }
19+ Y.one('#request-daily-build-form').addClass('unseen');
20+};
21+
22+
23 namespace.connect_requestbuilds = function(config) {
24 var io_provider = Y.lp.client.get_configured_io_provider(config),
25 request_build_handle = Y.one('#request-builds');
26
27=== modified file 'lib/lp/code/javascript/tests/test_requestbuild_overlay.html'
28--- lib/lp/code/javascript/tests/test_requestbuild_overlay.html 2012-03-14 04:41:36 +0000
29+++ lib/lp/code/javascript/tests/test_requestbuild_overlay.html 2012-04-28 03:27:31 +0000
30@@ -89,5 +89,21 @@
31 </div>
32 </script>
33
34+ <script type="text/x-template" id="build-schedule-template">
35+ <form action="+request-daily-build"
36+ method="post" id="request-daily-build-form">
37+ <input type="submit" name="field.actions.build"
38+ id="field.actions.build" value="Build now" />
39+ </form>
40+ <a id="request-daily-build"
41+ class="sprite source-package-recipe js-action unseen"
42+ href="+build-now">Build now</a>
43+ <div id="builds-target">
44+ <div>
45+ <a id="request-builds"
46+ class="" href="#">Request build(s)</a>
47+ </div>
48+ </div>
49+ </script>
50 </body>
51 </html>
52
53=== modified file 'lib/lp/code/javascript/tests/test_requestbuild_overlay.js'
54--- lib/lp/code/javascript/tests/test_requestbuild_overlay.js 2011-08-30 13:32:12 +0000
55+++ lib/lp/code/javascript/tests/test_requestbuild_overlay.js 2012-04-28 03:27:31 +0000
56@@ -18,18 +18,18 @@
57 LP.cache.context = {
58 web_link: "http://code.launchpad.dev/~foobar/myrecipe"};
59 // Prepare testbed.
60- var testbed = Y.one("#testbed").set('innerHTML', '');
61- testbed.append(
62- Y.Node.create('<a></a>')
63- .set('id', 'request-daily-build')
64- .set('href', '#')
65- .addClass('unseen')
66- .set('text', 'Build now')
67- ).append(
68- Y.Node.create('<div></div>')
69- .set('id', 'builds-target')
70- );
71- },
72+ fixture = Y.one("#testbed");
73+ var template = Y.one('#build-schedule-template').getContent();
74+ var test_node = Y.Node.create(template);
75+ fixture.append(test_node);
76+ },
77+
78+ tearDown: function() {
79+ Y.one("#testbed").empty();
80+ LP.cache.context = {};
81+ LP.cache.links = {};
82+ },
83+
84
85 _makeRequest: function() {
86 var mockio = new Y.lp.testing.mockio.MockIo();
87@@ -112,22 +112,17 @@
88 web_link: "http://code.launchpad.dev/~foobar/myrecipe",
89 self_link: "http://api.launchpad.dev/devel/~foobar/myrecipe"};
90 // Prepare testbed.
91- var testbed = Y.one("#testbed").set('innerHTML', '');
92- testbed.append(
93- Y.Node.create('<div></div>')
94- .set('id', 'builds-target')
95- ).append(
96- Y.Node.create('<div></div>').append(
97- Y.Node.create('<a></a>')
98- .set('id', 'request-builds')
99- .set('href', '#')
100- .set('text', 'Request build(s)')
101- )
102- );
103+ fixture = Y.one("#testbed");
104+ var template = Y.one('#build-schedule-template').getContent();
105+ var test_node = Y.Node.create(template);
106+ fixture.append(test_node);
107 },
108
109 tearDown: function() {
110 module.destroy_requestbuilds();
111+ Y.one("#testbed").empty();
112+ LP.cache.context = {};
113+ LP.cache.links = {};
114 },
115
116 _makeRequest: function() {
117@@ -237,6 +232,42 @@
118 }
119 }));
120
121+
122+suite.add(new Y.Test.Case({
123+ name: "lp.code.requestbuild_overlay.buildschedule",
124+
125+ setUp: function() {
126+ fixture = Y.one("#testbed");
127+ var template = Y.one('#build-schedule-template').getContent();
128+ var test_node = Y.Node.create(template);
129+ fixture.append(test_node);
130+ },
131+
132+ tearDown: function() {
133+ Y.one("#testbed").empty();
134+ LP.cache.context = {};
135+ LP.cache.links = {};
136+ },
137+
138+ test_hookUpDailyBuildsSchedule_anonymous: function() {
139+ module.hookUpDailyBuildsSchedule();
140+ Y.Assert.isTrue(
141+ Y.one('#request-daily-build-form').hasClass('unseen'));
142+ Y.Assert.isTrue(
143+ Y.one('#request-daily-build').hasClass('unseen'));
144+ },
145+
146+ test_hookUpDailyBuildsSchedule_logged_in_user: function() {
147+ LP.links.me = '/~name16';
148+ module.hookUpDailyBuildsSchedule();
149+ Y.Assert.isTrue(
150+ Y.one('#request-daily-build-form').hasClass('unseen'));
151+ Y.Assert.isFalse(
152+ Y.one('#request-daily-build').hasClass('unseen'));
153+ }
154+}));
155+
156+
157 Y.lp.testing.Runner.run(suite);
158
159 });
160
161=== added file 'lib/lp/code/javascript/tests/test_util.html'
162--- lib/lp/code/javascript/tests/test_util.html 1970-01-01 00:00:00 +0000
163+++ lib/lp/code/javascript/tests/test_util.html 2012-04-28 03:27:31 +0000
164@@ -0,0 +1,85 @@
165+<!DOCTYPE html>
166+<!--
167+Copyright 2012 Canonical Ltd. This software is licensed under the
168+GNU Affero General Public License version 3 (see the file LICENSE).
169+-->
170+
171+<html>
172+ <head>
173+ <title>Test requestbuild_overlay</title>
174+
175+ <!-- YUI and test setup -->
176+ <script type="text/javascript"
177+ src="../../../../../build/js/yui/yui/yui.js">
178+ </script>
179+ <link rel="stylesheet"
180+ href="../../../../../build/js/yui/console/assets/console-core.css" />
181+ <link rel="stylesheet"
182+ href="../../../../../build/js/yui/console/assets/skins/sam/console.css" />
183+ <link rel="stylesheet"
184+ href="../../../../../build/js/yui/test/assets/skins/sam/test.css" />
185+
186+ <script type="text/javascript"
187+ src="../../../../../build/js/lp/app/testing/testrunner.js"></script>
188+ <link rel="stylesheet" href="../../../app/javascript/testing/test.css" />
189+
190+ <!-- The module under test. -->
191+ <script type="text/javascript" src="../util.js"></script>
192+
193+ <!-- The test suite. -->
194+ <script type="text/javascript" src="test_util.js"></script>
195+ </head>
196+ <body class="yui3-skin-sam">
197+ <ul id="suites">
198+ <li>lp.code.util.test</li>
199+ </ul>
200+
201+ <div id="fixture"></div>
202+
203+ <script type="text/x-template" id="daily-builds-form">
204+ <form name="filter" id="filter_form" action="/+test">
205+ <select id="field.when_completed_filter"
206+ name="field.when_completed_filter" size="1">
207+ <option selected="selected" value="ALL">All</option>
208+ <option value="WITHIN_30_DAYS">Recent</option>
209+ </select>
210+ <input id="filter_form_submit" type="submit" value="Filter"/>
211+ </form>
212+ </script>
213+
214+ <script type="text/x-template" id="branch-listing-form">
215+ <form name="filter" id="filter_form" action="/+test">
216+ <select id="field.lifecycle" name="field.lifecycle" size="1">
217+ <option selected="selected" value="ALL">All</option>
218+ <option value="Active">Active</option>
219+ </select>
220+ <select id="field.sort_by" name="field.sort_by" size="1">
221+ <option selected="selected" value="NEW">Newest</option>
222+ <option value="OLD">Oldest</option>
223+ </select>
224+ <input id="filter_form_submit" type="submit" value="Filter"/>
225+ </form>
226+ </script>
227+
228+ <script type="text/x-template" id="merge-proposal-form">
229+ <form name="filter" id="filter_form" action="/+test">
230+ <select id="field.status"
231+ name="field.status" size="1">
232+ <option selected="selected" value="ALL">All</option>
233+ <option value="WITHIN_30_DAYS">Recent</option>
234+ </select>
235+ <input id="filter_form_submit" type="submit" value="Filter"/>
236+ </form>
237+ </script>
238+
239+ <script type="text/x-template" id="retry-import-form">
240+ <form name="tryagain" id="tryagain" action="/+test">
241+ <input type="hidden" name="tryagain.actions.tryagain"
242+ value="" />
243+ <input type="submit" id="tryagain.actions.tryagain"
244+ name="tryagain.actions.tryagain" value="Try Again" />
245+ <a class="unseen" id="tryagainlink" href="#">Try again</a>
246+ </form>
247+ </script>
248+ </body>
249+</html>
250
251=== added file 'lib/lp/code/javascript/tests/test_util.js'
252--- lib/lp/code/javascript/tests/test_util.js 1970-01-01 00:00:00 +0000
253+++ lib/lp/code/javascript/tests/test_util.js 2012-04-28 03:27:31 +0000
254@@ -0,0 +1,90 @@
255+/* Copyright (c) 2012, Canonical Ltd. All rights reserved. */
256+
257+YUI().use('test', 'console', 'node-event-simulate', 'lp.testing.runner',
258+ 'lp.code.util', function(Y) {
259+
260+var suite = new Y.Test.Suite("lp.code.util Tests");
261+var module = Y.lp.code.util;
262+
263+
264+suite.add(new Y.Test.Case({
265+ name: "lp.code.util",
266+
267+ setUp: function() {
268+ this.fixture = Y.one("#fixture");
269+ this.listener = {event_fired: false};
270+ },
271+
272+ tearDown: function () {
273+ if (this.fixture !== null) {
274+ this.fixture.empty();
275+ }
276+ delete this.fixture;
277+ },
278+
279+ _setup_fixture: function(template_selector) {
280+ var template =Y.one(template_selector).getContent();
281+ var test_node = Y.Node.create(template);
282+ this.fixture.append(test_node);
283+ },
284+
285+ _add_submit_listener: function(form_selector) {
286+ // prevent submission when the form's method is directly invoked
287+ // and record that the methods was called.
288+ var listener = this.listener;
289+ Y.one(form_selector).submit = function(e) {
290+ listener.event_fired = true;
291+ e.halt();
292+ };
293+ },
294+
295+ test_hookUpDailyBuildsFilterSubmission: function() {
296+ this._setup_fixture('#daily-builds-form');
297+ module.hookUpDailyBuildsFilterSubmission();
298+ this._add_submit_listener('#filter_form');
299+ Y.one('[id=field.when_completed_filter]').simulate('change');
300+ Y.Assert.isTrue(this.listener.event_fired);
301+ Y.Assert.isTrue(
302+ Y.one('#filter_form_submit').hasClass('unseen'));
303+ },
304+
305+ test_hookUpBranchFilterSubmission: function() {
306+ this._setup_fixture('#branch-listing-form');
307+ module.hookUpBranchFilterSubmission();
308+ this._add_submit_listener('#filter_form');
309+ Y.one('[id=field.lifecycle]').simulate('change');
310+ Y.Assert.isTrue(this.listener.event_fired);
311+ this.listener.event_fired = false;
312+ Y.one('[id=field.sort_by]').simulate('change');
313+ Y.Assert.isTrue(this.listener.event_fired);
314+ Y.Assert.isTrue(
315+ Y.one('#filter_form_submit').hasClass('unseen'));
316+ },
317+
318+ test_hookUpMergeProposalFilterSubmission: function() {
319+ this._setup_fixture('#merge-proposal-form');
320+ module.hookUpMergeProposalFilterSubmission();
321+ this._add_submit_listener('#filter_form');
322+ Y.one('[id=field.status]').simulate('change');
323+ Y.Assert.isTrue(this.listener.event_fired);
324+ Y.Assert.isTrue(
325+ Y.one('#filter_form_submit').hasClass('unseen'));
326+ },
327+
328+ test_hookUpRetyImportSubmission: function() {
329+ this._setup_fixture('#retry-import-form');
330+ module.hookUpRetyImportSubmission();
331+ this._add_submit_listener('#tryagain');
332+ var try_again_link = Y.one("#tryagainlink");
333+ try_again_link.simulate('click');
334+ Y.Assert.isTrue(this.listener.event_fired);
335+ Y.Assert.isFalse(try_again_link.hasClass('unseen'));
336+ Y.Assert.isTrue(
337+ Y.one('[id=tryagain.actions.tryagain]').hasClass('unseen'));
338+ }
339+
340+}));
341+
342+Y.lp.testing.Runner.run(suite);
343+
344+});
345
346=== modified file 'lib/lp/code/javascript/util.js'
347--- lib/lp/code/javascript/util.js 2012-02-07 18:38:52 +0000
348+++ lib/lp/code/javascript/util.js 2012-04-28 03:27:31 +0000
349@@ -1,7 +1,7 @@
350 /* Copyright 2012 Canonical Ltd. This software is licensed under the
351 * GNU Affero General Public License version 3 (see the file LICENSE).
352 *
353- * Control enabling/disabling form elements on the +new-recipe page.
354+ * Control enabling/disabling form elements on Code domain pages.
355 *
356 * @module Y.lp.code.util
357 * @requires node
358@@ -31,30 +31,44 @@
359 update_branch_unique_name();
360 };
361
362+var submit_filter = function (e) {
363+ Y.one('#filter_form').submit();
364+};
365+
366 var hookUpBranchFilterSubmission = function() {
367- var submit_filter = function (e) {
368- Y.DOM.byId('filter_form').submit();
369- };
370-
371 Y.one("[id='field.lifecycle']").on('change', submit_filter);
372 var sortby = Y.one("[id='field.sort_by']");
373 if (Y.Lang.isValue(sortby)) {
374 sortby.on('change', submit_filter);
375 }
376+ Y.one('#filter_form_submit').addClass('unseen');
377 };
378
379 var hookUpDailyBuildsFilterSubmission = function() {
380- var submit_filter = function (e) {
381- Y.DOM.byId('filter_form').submit();
382- };
383-
384 Y.one("[id='field.when_completed_filter']").on(
385 'change', submit_filter);
386+ Y.one('#filter_form_submit').addClass('unseen');
387+};
388+
389+var hookUpMergeProposalFilterSubmission = function() {
390+ Y.one("[id=field.status]").on('change', submit_filter);
391+ Y.one('#filter_form_submit').addClass('unseen');
392+};
393+
394+var hookUpRetyImportSubmission = function() {
395+ var try_again_link = Y.one("#tryagainlink");
396+ try_again_link.on('click', function (e) {
397+ Y.one('#tryagain').submit();
398+ });
399+ try_again_link.removeClass('unseen');
400+ Y.one('[id=tryagain.actions.tryagain]').addClass('unseen');
401 };
402
403 ns.hookUpBranchFieldFunctions = hookUpBranchFieldFunctions;
404 ns.hookUpBranchFilterSubmission = hookUpBranchFilterSubmission;
405 ns.hookUpDailyBuildsFilterSubmission = hookUpDailyBuildsFilterSubmission;
406+ns.hookUpMergeProposalFilterSubmission = hookUpMergeProposalFilterSubmission;
407+ns.hookUpRetyImportSubmission = hookUpRetyImportSubmission;
408
409 }, "0.1", {"requires": ["node", "dom"]});
410
411
412=== modified file 'lib/lp/code/templates/branch-import-details.pt'
413--- lib/lp/code/templates/branch-import-details.pt 2012-02-01 15:31:32 +0000
414+++ lib/lp/code/templates/branch-import-details.pt 2012-04-28 03:27:31 +0000
415@@ -16,25 +16,24 @@
416 <form tal:attributes="action string:${context/fmt:url}/@@+try-again"
417 tal:condition="python:view.user and code_import.review_status.name == 'FAILING'"
418 style="display: inline; padding-left: 1em"
419+ id="tryagain"
420 name="tryagain"
421 method="post"
422 enctype="multipart/form-data" accept-charset="UTF-8">
423- <noscript>
424- <img src="/@@/retry" />
425- <input id="tryagain.actions.tryagain" name="tryagain.actions.tryagain" value="Try Again" class="button" type="submit" />
426- </noscript>
427 <input
428 type="hidden"
429 name="tryagain.actions.tryagain"
430 value="" />
431- <a href="javascript:document.tryagain.submit()" class="hidden" id="tryagainlink">
432- <img src="/@@/retry" />
433- Try again
434- </a>
435+ <input type="submit" id="tryagain.actions.tryagain"
436+ name="tryagain.actions.tryagain" value="Try Again"
437+ class="button" />
438+ <a href="#" class="unseen sprite retry"
439+ id="tryagainlink">Try again</a>
440 <script type="text/javascript">
441- LPJS.use('event', 'node', function(Y) {
442- Y.on("domready", function () { Y.one('#tryagainlink').setStyle('display', 'inline') });
443- });
444+ LPJS.use('lp.code.util', function(Y) {
445+ Y.on("domready", function () {
446+ Y.lp.code.util.hookUpRetyImportSubmission(Y);
447+ }, window);});
448 </script>
449 </form>
450 </div>
451
452=== modified file 'lib/lp/code/templates/branch-listing.pt'
453--- lib/lp/code/templates/branch-listing.pt 2012-02-01 15:31:32 +0000
454+++ lib/lp/code/templates/branch-listing.pt 2012-04-28 03:27:31 +0000
455@@ -11,9 +11,7 @@
456 <tal:lifecycle-selector replace="structure context/view/widgets/lifecycle"/>
457 <tal:sort-by replace="structure context/view/widgets/sort_by"
458 condition="context/view/widgets/sort_by|nothing"/>
459- <noscript>
460- <input type="submit" value="Filter"/>
461- </noscript>
462+ <input id="filter_form_submit" type="submit" value="Filter"/>
463 </form>
464
465 <script type="text/javascript">
466
467=== modified file 'lib/lp/code/templates/branchmergeproposal-generic-listing.pt'
468--- lib/lp/code/templates/branchmergeproposal-generic-listing.pt 2012-02-01 15:31:32 +0000
469+++ lib/lp/code/templates/branchmergeproposal-generic-listing.pt 2012-04-28 03:27:31 +0000
470@@ -18,22 +18,14 @@
471 Proposals with status:
472 </label>
473 <tal:lifecycle-selector replace="structure view/widgets/status"/>
474- <noscript>
475- <input type="submit" value="Filter"/>
476- </noscript>
477+ <input id="filter_form_submit" type="submit" value="Filter"/>
478 </form>
479 <script type="text/javascript">
480
481-LPJS.use('node', function(Y) {
482-
483- function submit_filter() {
484- Y.one('#filter_form').submit();
485- }
486- Y.on('domready', function () {
487- var field = Y.one("[id=field.status]");
488- field.on('change', submit_filter);
489- });
490-
491+LPJS.use("lp.code.util", function(Y) {
492+ Y.on("domready", function(e) {
493+ Y.lp.code.util.hookUpMergeProposalFilterSubmission(Y);
494+ }, window);
495 });
496
497 </script>
498
499=== modified file 'lib/lp/code/templates/daily-builds-listing.pt'
500--- lib/lp/code/templates/daily-builds-listing.pt 2012-02-01 15:31:32 +0000
501+++ lib/lp/code/templates/daily-builds-listing.pt 2012-04-28 03:27:31 +0000
502@@ -23,9 +23,7 @@
503 class="sprite maybe"
504 >&nbsp;<span class="invisible-link">Tag help</span></a>build
505 <tal:build-age-selector replace="structure view/widgets/when_completed_filter"/>
506- <noscript>
507- <input type="submit" value="Filter"/>
508- </noscript>
509+ <input id="filter_form_submit" type="submit" value="Filter"/>
510 </form>
511
512 <script type="text/javascript">
513
514=== modified file 'lib/lp/code/templates/sourcepackagerecipe-index.pt'
515--- lib/lp/code/templates/sourcepackagerecipe-index.pt 2012-02-01 15:31:32 +0000
516+++ lib/lp/code/templates/sourcepackagerecipe-index.pt 2012-04-28 03:27:31 +0000
517@@ -92,14 +92,12 @@
518 tal:define="link context/menu:context/request_daily_build"
519 tal:condition="link/enabled"
520 >
521- <noscript>
522- <form action="+request-daily-build"
523- method="post"
524- id="request-daily-build-form">
525- <input type="submit" name="field.actions.build"
526- id="field.actions.build" value="Build now" />
527- </form>
528- </noscript>
529+ <form action="+request-daily-build"
530+ method="post"
531+ id="request-daily-build-form">
532+ <input type="submit" name="field.actions.build"
533+ id="field.actions.build" value="Build now" />
534+ </form>
535 <a id="request-daily-build"
536 class="sprite source-package-recipe js-action unseen"
537 tal:attributes="href link/url"
538@@ -162,16 +160,7 @@
539 return;
540 }
541 Y.on('load', function() {
542- var logged_in = LP.links['me'] !== undefined;
543- if (logged_in) {
544- build_now_link = Y.one('#request-daily-build');
545- if( build_now_link != null ) {
546- build_now_link.removeClass('unseen');
547- Y.lp.code.requestbuild_overlay.connect_requestdailybuild();
548- }
549- Y.lp.code.requestbuild_overlay.connect_requestbuilds();
550-
551- }
552+ Y.lp.code.requestbuild_overlay.hookUpDailyBuildsSchedule();
553 }, window);
554 });
555 </script>
556
557=== modified file 'lib/lp/translations/javascript/importqueue.js'
558--- lib/lp/translations/javascript/importqueue.js 2012-03-02 16:17:46 +0000
559+++ lib/lp/translations/javascript/importqueue.js 2012-04-28 03:27:31 +0000
560@@ -175,6 +175,10 @@
561
562 // Set up status pickers.
563 Y.all('.status-choice').each(init_status_choice);
564+ Y.all('.status-select').each(function(content_box, index, list) {
565+ content_box.addClass('hidden');
566+ });
567+ Y.one('#import-queue-submit').addClass('hidden');
568 };
569
570 }, "0.1", {
571
572=== added file 'lib/lp/translations/javascript/tests/test_importqueue.html'
573--- lib/lp/translations/javascript/tests/test_importqueue.html 1970-01-01 00:00:00 +0000
574+++ lib/lp/translations/javascript/tests/test_importqueue.html 2012-04-28 03:27:31 +0000
575@@ -0,0 +1,110 @@
576+<!DOCTYPE html>
577+<!--
578+Copyright 2012 Canonical Ltd. This software is licensed under the
579+GNU Affero General Public License version 3 (see the file LICENSE).
580+-->
581+
582+<html>
583+ <head>
584+ <title>Test importqueue</title>
585+
586+ <!-- YUI and test setup -->
587+ <script type="text/javascript"
588+ src="../../../../../build/js/yui/yui/yui.js">
589+ </script>
590+ <link rel="stylesheet"
591+ href="../../../../../build/js/yui/console/assets/console-core.css" />
592+ <link rel="stylesheet"
593+ href="../../../../../build/js/yui/console/assets/skins/sam/console.css" />
594+ <link rel="stylesheet"
595+ href="../../../../../build/js/yui/test/assets/skins/sam/test.css" />
596+
597+ <script type="text/javascript"
598+ src="../../../../../build/js/lp/app/testing/testrunner.js"></script>
599+
600+ <link rel="stylesheet" href="../../../app/javascript/testing/test.css" />
601+
602+ <!-- Dependencies -->
603+ <script type="text/javascript"
604+ src="../../../../../build/js/lp/app/lazr/lazr.js"></script>
605+ <script type="text/javascript"
606+ src="../../../../../build/js/lp/app/overlay/overlay.js"></script>
607+ <script type="text/javascript"
608+ src="../../../../../build/js/lp/app/anim/amin.js"></script>
609+ <script type="text/javascript"
610+ src="../../../../../build/js/lp/app/choiceedit/choiceedit.js"></script>
611+ <script type="text/javascript"
612+ src="../../../../../build/js/lp/app/client.js"></script>
613+ <script type="text/javascript"
614+ src="../../../../../build/js/lp/app/errors.js"></script>
615+
616+ <!-- The module under test. -->
617+ <script type="text/javascript" src="../importqueue.js"></script>
618+
619+ <!-- The test suite. -->
620+ <script type="text/javascript" src="test_importqueue.js"></script>
621+
622+ </head>
623+ <body class="yui3-skin-sam">
624+ <ul id="suites">
625+ <li>lp.translations.importqueue.test</li>
626+ </ul>
627+
628+ <div id="fixture"></div>
629+
630+ <script type="text/javascript">
631+ var choice_confs = [];
632+ </script>
633+
634+ <script type="text/x-template" id="import-queue-listing">
635+ <table id="import-entries-list" class="listing">
636+ <tr class="import_entry_row" id="1">
637+ <td class="import_source">
638+ po/evolution-2.2-test.pot in Evolution trunk series
639+ </td>
640+
641+ <td class="import_status">
642+ <span class="status-select">
643+ <select id="field.status_1" name="field.status_1">
644+ <option value="APPROVED">Approved</option>
645+ <option selected="selected"
646+ value="IMPORTED">Imported</option>
647+ </select>
648+ </span>
649+ <span class="status-choice hidden">
650+ <span class="value translationimportstatusIMPORTED">
651+ Imported</span>
652+ <img class="editicon" src="/@@/edit" />
653+ </span>
654+ </td>
655+ </tr>
656+
657+ <tr class="import_entry_row" id="2">
658+ <td class="import_source">
659+ po/pt_BR.po in Evolution trunk series
660+ </td>
661+
662+ <td class="import_status">
663+ <span class="status-select">
664+ <select id="field.status_2" name="field.status_2">
665+ <option value="APPROVED">Approved</option>
666+ <option selected="selected"
667+ value="IMPORTED">Imported</option>
668+ </select>
669+ </span>
670+ <span class="status-choice hidden">
671+ <span class="value translationimportstatusIMPORTED">
672+ Imported</span>
673+ <img class="editicon" src="/@@/edit" />
674+ </span>
675+ </td>
676+ </tr>
677+ </table>
678+
679+ <div id="import-queue-submit" class="actions">
680+ <input type="submit" id="field.actions.change_status"
681+ name="field.actions.change_status" value="Change status" />
682+ </div>
683+ </script>
684+ </body>
685+</html>
686
687=== added file 'lib/lp/translations/javascript/tests/test_importqueue.js'
688--- lib/lp/translations/javascript/tests/test_importqueue.js 1970-01-01 00:00:00 +0000
689+++ lib/lp/translations/javascript/tests/test_importqueue.js 2012-04-28 03:27:31 +0000
690@@ -0,0 +1,67 @@
691+/* Copyright 2011 Canonical Ltd. This software is licensed under the
692+ * GNU Affero General Public License version 3 (see the file LICENSE).
693+ */
694+
695+YUI().use('lp.testing.runner', 'test', 'console',
696+ 'lp.translations.importqueue', function(Y) {
697+
698+var suite = new Y.Test.Suite("importqueue Tests");
699+var namespace = Y.lp.translations.importqueue;
700+
701+
702+var make_choice_confs = function() {
703+ // Make generic confs fot testing. The test can change these as needed.
704+ var confs = [];
705+ var values = ['Imported', 'Imported'];
706+ var statuses = ['Approved', 'Imported'];
707+ Y.Array.forEach(values, function(value) {
708+ var conf = {
709+ 'value': value,
710+ 'items': []
711+ };
712+ Y.Array.forEach(statuses, function(status) {
713+ conf.items.push({
714+ 'style': '',
715+ 'help': '',
716+ 'css_class': 'translationimportstatus' + status,
717+ 'description': '',
718+ 'value': status,
719+ 'disabled': false,
720+ 'description_css_class': 'choice-description',
721+ 'name': status
722+ });
723+ });
724+ confs.push(conf);
725+ });
726+ return confs;
727+};
728+
729+
730+suite.add(new Y.Test.Case({
731+ name: 'importqueue macros',
732+
733+ setUp: function() {
734+ fixture = Y.one("#fixture");
735+ var template = Y.one('#import-queue-listing').getContent();
736+ var test_node = Y.Node.create(template);
737+ fixture.append(test_node);
738+ },
739+
740+ tearDown: function() {
741+ Y.one("#fixture").empty();
742+ },
743+
744+ test_initialize_import_queue_page: function() {
745+ choice_confs = make_choice_confs(); // setup global choice_confs.
746+ namespace.initialize_import_queue_page(Y);
747+ Y.Assert.isTrue(
748+ Y.one('#import-queue-submit').hasClass('hidden'));
749+ Y.Assert.isTrue(
750+ Y.one('.status-select').hasClass('hidden'));
751+ status_choice = Y.one('.status-choice');
752+ Y.Assert.isFalse(status_choice.hasClass('hidden'));
753+ }
754+}));
755+
756+Y.lp.testing.Runner.run(suite);
757+});
758
759=== modified file 'lib/lp/translations/templates/pofile-export.pt'
760--- lib/lp/translations/templates/pofile-export.pt 2012-02-01 15:31:32 +0000
761+++ lib/lp/translations/templates/pofile-export.pt 2012-04-28 03:27:31 +0000
762@@ -32,6 +32,7 @@
763 formatlist.on('change', toggle_pochanged);
764 // Initialize the state of the controls.
765 toggle_pochanged();
766+ Y.one('#po-format-only').addClass('unseen');
767 });
768 });
769 </script>
770@@ -65,7 +66,7 @@
771 <input type="checkbox" name="pochanged" id="cb_pochanged"
772 value="POCHANGED" />
773 <label for="cb_pochanged">
774- <span><noscript><em>PO format only:</em></noscript>
775+ <span><em id="po-format-only">PO format only:</em>
776 Only strings that differ from imported versions
777 (<a href="https://help.launchpad.net/Translations/PartialPOExport"
778 target="_blank">What's this?</a>).</span>
779
780=== modified file 'lib/lp/translations/templates/translation-import-queue-macros.pt'
781--- lib/lp/translations/templates/translation-import-queue-macros.pt 2012-03-02 16:17:46 +0000
782+++ lib/lp/translations/templates/translation-import-queue-macros.pt 2012-04-28 03:27:31 +0000
783@@ -93,10 +93,10 @@
784 omit-tag="">
785 <td class="import_status"
786 tal:condition="entry/required:launchpad.Edit">
787- <noscript>
788+ <span class="status-select">
789 <tal:status define="name string:status_${entry/id}"
790 replace="structure view/widgets/?name" />
791- </noscript>
792+ </span>
793 <span class="status-choice hidden">
794 <span tal:attributes="class string:value ${css_status}"
795 tal:content="entry/status/title">
796@@ -171,18 +171,16 @@
797 <tal:navigation
798 replace="structure view/batchnav/@@+navigation-links-lower" />
799
800+ <tal:block define="user request/lp:person" condition="user">
801+ <div id="import-queue-submit" class="actions">
802+ <input
803+ tal:replace="structure view/change_status_action/render" />
804+ </div>
805+ </tal:block>
806 <script type="text/javascript"
807 tal:define="script view/focusedElementScript"
808 tal:condition="script"
809 tal:content="structure script" />
810- <tal:block define="user request/lp:person" condition="user">
811- <noscript>
812- <div class="actions">
813- <input
814- tal:replace="structure view/change_status_action/render" />
815- </div>
816- </noscript>
817- </tal:block>
818 </form>
819 </tal:block>
820 </div>