Merge lp:~allenap/launchpad/localpackagediffs-filter-by-package-set-bug-809786-split-formwidgets into lp:launchpad
- localpackagediffs-filter-by-package-set-bug-809786-split-formwidgets
- Merge into devel
Proposed by
Gavin Panella
Status: | Merged |
---|---|
Approved by: | Gavin Panella |
Approved revision: | no longer in the source branch. |
Merged at revision: | 13463 |
Proposed branch: | lp:~allenap/launchpad/localpackagediffs-filter-by-package-set-bug-809786-split-formwidgets |
Merge into: | lp:launchpad |
Prerequisite: | lp:~allenap/launchpad/localpackagediffs-filter-by-package-set-bug-809786-split |
Diff against target: |
2878 lines (+1371/-1241) 9 files modified
lib/lp/app/javascript/formwidgets/formwidgets.js (+626/-0) lib/lp/app/javascript/formwidgets/tests/test_formwidgets.html (+47/-0) lib/lp/app/javascript/formwidgets/tests/test_formwidgets.js (+605/-0) lib/lp/registry/javascript/distroseries/initseries.js (+7/-6) lib/lp/registry/javascript/distroseries/tests/test_initseries.html (+28/-26) lib/lp/registry/javascript/distroseries/tests/test_initseries.js (+4/-4) lib/lp/registry/javascript/distroseries/tests/test_widgets.html (+29/-23) lib/lp/registry/javascript/distroseries/tests/test_widgets.js (+13/-569) lib/lp/registry/javascript/distroseries/widgets.js (+12/-613) |
To merge this branch: | bzr merge lp:~allenap/launchpad/localpackagediffs-filter-by-package-set-bug-809786-split-formwidgets |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gavin Panella (community) | Approve | ||
Review via email: mp+68237@code.launchpad.net |
Commit message
[r=allenap][bug=809786] Split out the non-DistroSerie
Description of the change
This splits out the non-DistroSerie
To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'lib/lp/app/javascript/formwidgets' |
2 | === added file 'lib/lp/app/javascript/formwidgets/formwidgets.js' |
3 | --- lib/lp/app/javascript/formwidgets/formwidgets.js 1970-01-01 00:00:00 +0000 |
4 | +++ lib/lp/app/javascript/formwidgets/formwidgets.js 2011-07-18 11:56:36 +0000 |
5 | @@ -0,0 +1,626 @@ |
6 | +/** |
7 | + * Copyright 2011 Canonical Ltd. This software is licensed under the |
8 | + * GNU Affero General Public License version 3 (see the file LICENSE). |
9 | + * |
10 | + * Form Widgets. |
11 | + * |
12 | + * @module lp.app |
13 | + * @submodule formwidgets |
14 | + */ |
15 | + |
16 | +YUI.add('lp.app.formwidgets', function(Y) { |
17 | + |
18 | +Y.log('loading lp.app.formwidgets'); |
19 | + |
20 | +var namespace = Y.namespace('lp.app.formwidgets'); |
21 | + |
22 | + |
23 | +/** |
24 | + * A form row matching that which LaunchpadForm presents, containing a |
25 | + * field (defined in a subclass), and an optional label and |
26 | + * description. |
27 | + * |
28 | + * @class FormRowWidget |
29 | + */ |
30 | +var FormRowWidget; |
31 | + |
32 | +FormRowWidget = function() { |
33 | + FormRowWidget.superclass.constructor.apply(this, arguments); |
34 | +}; |
35 | + |
36 | +Y.mix(FormRowWidget, { |
37 | + |
38 | + NAME: 'formRowWidget', |
39 | + |
40 | + ATTRS: { |
41 | + |
42 | + /** |
43 | + * The field name. |
44 | + * |
45 | + * @property name |
46 | + */ |
47 | + name: { |
48 | + setter: function(value, name) { |
49 | + this.fieldNode.all("input, select").set("name", value); |
50 | + } |
51 | + }, |
52 | + |
53 | + /** |
54 | + * The top label for the field. |
55 | + * |
56 | + * @property label |
57 | + */ |
58 | + label: { |
59 | + getter: function() { |
60 | + return this.labelNode.get("text"); |
61 | + }, |
62 | + setter: function(value, name) { |
63 | + this.labelNode.set("text", value); |
64 | + } |
65 | + }, |
66 | + |
67 | + /** |
68 | + * A dictionary {link:link, text:text} to populate |
69 | + * the pop-up help for the field. |
70 | + * |
71 | + * @property help |
72 | + */ |
73 | + help: { |
74 | + getter: function() { |
75 | + return {link:this.helpNode.one('a') |
76 | + .get("href"), |
77 | + text:this.helpNode |
78 | + .one('.invisible-link') |
79 | + .get("text")}; |
80 | + }, |
81 | + setter: function(value, name) { |
82 | + if ((value.link !== undefined) && |
83 | + (value.text !== undefined)) { |
84 | + this.helpNode.one('a').set("href", value.link); |
85 | + this.helpNode.one('.invisible-link') |
86 | + .set("text", value.text); |
87 | + this.helpNode.removeClass('unseen'); |
88 | + } |
89 | + else { |
90 | + this.helpNode.addClass('unseen'); |
91 | + } |
92 | + } |
93 | + }, |
94 | + |
95 | + /** |
96 | + * A description shown near the field. |
97 | + * |
98 | + * @label description |
99 | + */ |
100 | + description: { |
101 | + getter: function() { |
102 | + return this.descriptionNode.get("text"); |
103 | + }, |
104 | + setter: function(value, name) { |
105 | + this.descriptionNode.set("text", value); |
106 | + } |
107 | + } |
108 | + } |
109 | + |
110 | +}); |
111 | + |
112 | +Y.extend(FormRowWidget, Y.Widget, { |
113 | + |
114 | + BOUNDING_TEMPLATE: "<tr></tr>", |
115 | + |
116 | + CONTENT_TEMPLATE: '<td colspan="2"></td>', |
117 | + |
118 | + initializer: function(config) { |
119 | + this.labelNode = Y.Node.create("<label />"); |
120 | + this.helpNode = Y.Node.create(('<span class="helper unseen">'+ |
121 | + ' <a href=""' + |
122 | + 'target="help" class="sprite maybe"> ' + |
123 | + '<span class="invisible-link"></span></a></span>')); |
124 | + this.fieldNode = Y.Node.create("<div></div>"); |
125 | + this.descriptionNode = Y.Node.create('<p class="formHelp" />'); |
126 | + this.spinnerNode = Y.Node.create( |
127 | + '<img src="/@@/spinner" alt="Loading..." />'); |
128 | + }, |
129 | + |
130 | + renderUI: function() { |
131 | + this.get("contentBox") |
132 | + .append(this.labelNode) |
133 | + .append(this.helpNode) |
134 | + .append(this.fieldNode) |
135 | + .append(this.descriptionNode); |
136 | + }, |
137 | + |
138 | + /** |
139 | + * Show the spinner. |
140 | + * |
141 | + * @method showSpinner |
142 | + */ |
143 | + showSpinner: function() { |
144 | + this.fieldNode.empty().append(this.spinnerNode); |
145 | + }, |
146 | + |
147 | + /** |
148 | + * Hide the spinner. |
149 | + * |
150 | + * @method hideSpinner |
151 | + */ |
152 | + hideSpinner: function() { |
153 | + this.spinnerNode.remove(); |
154 | + }, |
155 | + |
156 | + /** |
157 | + * Display an error. |
158 | + * |
159 | + * @method showError |
160 | + */ |
161 | + showError: function(error) { |
162 | + var message = Y.Node.create('<p />').set("text", error); |
163 | + this.fieldNode.empty().append(message); |
164 | + Y.lazr.anim.red_flash({node: message}).run(); |
165 | + } |
166 | + |
167 | +}); |
168 | + |
169 | +namespace.FormRowWidget = FormRowWidget; |
170 | + |
171 | + |
172 | +/** |
173 | + * A form row matching that which LaunchpadForm presents, containing a |
174 | + * list of checkboxes, and an optional label and description. |
175 | + * |
176 | + * @class ChoiceListWidget |
177 | + */ |
178 | +var ChoiceListWidget; |
179 | + |
180 | +ChoiceListWidget = function() { |
181 | + ChoiceListWidget.superclass.constructor.apply(this, arguments); |
182 | +}; |
183 | + |
184 | +Y.mix(ChoiceListWidget, { |
185 | + |
186 | + NAME: 'choiceListWidget', |
187 | + |
188 | + ATTRS: { |
189 | + |
190 | + /** |
191 | + * An array of strings from which to choose. |
192 | + * |
193 | + * @property choices |
194 | + */ |
195 | + choices: { |
196 | + getter: function() { |
197 | + return this.fieldNode.all("li > input").get("value"); |
198 | + }, |
199 | + setter: function(value, name) { |
200 | + var choices = Y.Array.unique(value).sort(); |
201 | + var list = Y.Node.create("<ul />"); |
202 | + var self = this; |
203 | + choices.forEach( |
204 | + function(choice) { |
205 | + var item = self._createChoice(choice); |
206 | + list.append(item); |
207 | + } |
208 | + ); |
209 | + this.fieldNode.empty().append(list); |
210 | + } |
211 | + }, |
212 | + |
213 | + /** |
214 | + * The current selection. |
215 | + * |
216 | + * @property choice |
217 | + */ |
218 | + choice: { |
219 | + setter: function(value, name) { |
220 | + if (!Y.Lang.isArray(value)) { |
221 | + value = [value]; |
222 | + } |
223 | + this.fieldNode.all("li > input").each( |
224 | + function(node) { |
225 | + node.set( |
226 | + "checked", |
227 | + value.indexOf(node.get("value")) >= 0); |
228 | + } |
229 | + ); |
230 | + }, |
231 | + getter: function() { |
232 | + var choice = []; |
233 | + this.fieldNode.all("li > input").each( |
234 | + function(node) { |
235 | + if (node.get("checked")) { |
236 | + choice.push(node.get("value")); |
237 | + } |
238 | + } |
239 | + ); |
240 | + if (this.get("type") === "radio") { |
241 | + if (choice.length === 0) { |
242 | + choice = null; |
243 | + } |
244 | + else if (choice.length === 1) { |
245 | + choice = choice[0]; |
246 | + } |
247 | + else { |
248 | + choice = undefined; |
249 | + } |
250 | + } |
251 | + return choice; |
252 | + } |
253 | + }, |
254 | + |
255 | + /** |
256 | + * The input type to display. Choose from "checkbox" or "radio". |
257 | + * |
258 | + * @property type |
259 | + */ |
260 | + type: { |
261 | + value: "checkbox", |
262 | + setter: function(value, name) { |
263 | + this.fieldNode.all("li > input").set("type", value); |
264 | + } |
265 | + } |
266 | + |
267 | + } |
268 | + |
269 | +}); |
270 | + |
271 | +Y.extend(ChoiceListWidget, FormRowWidget, { |
272 | + |
273 | + /** |
274 | + * Helper method to create an entry for the select widget. |
275 | + * |
276 | + * @method _createChoice |
277 | + */ |
278 | + _createChoice: function(choice) { |
279 | + var field_name = this.get("name"); |
280 | + var field_type = this.get("type"); |
281 | + var item = Y.Node.create( |
282 | + "<li><input /> <label /></li>"); |
283 | + item.one("input") |
284 | + .set("type", field_type) |
285 | + .set("name", field_name) |
286 | + .set("value", choice); |
287 | + item.one("label") |
288 | + .setAttribute( |
289 | + "for", item.one("input").generateID()) |
290 | + .setStyle("font-weight", "normal") |
291 | + .set("text", choice); |
292 | + return item; |
293 | + }, |
294 | + |
295 | + /** |
296 | + * Remove a list of choices from the possible widget's choices. |
297 | + * |
298 | + * @method remove_choices |
299 | + */ |
300 | + remove_choices: function(choices) { |
301 | + choices.forEach( |
302 | + function(choice) { |
303 | + this.fieldNode.all("select > option").each( |
304 | + function(option) { options.push(option); }); |
305 | + this.fieldNode.all( |
306 | + "li input[value=" + choice + "]").each( |
307 | + function(li_input) { |
308 | + li_input.get('parentNode').remove(); |
309 | + } |
310 | + ); |
311 | + }, |
312 | + this |
313 | + ); |
314 | + Y.lazr.anim.green_flash({node: this.fieldNode}).run(); |
315 | + }, |
316 | + |
317 | + _sorted_position: function(choice) { |
318 | + var options = []; |
319 | + this.fieldNode.all("input").each( |
320 | + function(node) { |
321 | + options.push(node.get('value')); |
322 | + } |
323 | + ); |
324 | + options.push(choice); |
325 | + return options.sort().indexOf(choice); |
326 | + }, |
327 | + |
328 | + /** |
329 | + * Add new choices (if they are not already present). |
330 | + * |
331 | + * @method add_choices |
332 | + */ |
333 | + add_choices: function(new_choices) { |
334 | + new_choices.forEach( |
335 | + function(choice) { |
336 | + if (this.fieldNode.all( |
337 | + "li > input[value=" + choice + "]").isEmpty()) { |
338 | + var list = this.fieldNode.one('ul'); |
339 | + if (list === null) { |
340 | + list = Y.Node.create("<ul />"); |
341 | + this.fieldNode.empty().append(list); |
342 | + } |
343 | + var option = this._createChoice(choice); |
344 | + var options = list.all('input'); |
345 | + if (options.isEmpty()) { |
346 | + list.append(option); |
347 | + } |
348 | + else { |
349 | + var pos = this._sorted_position(choice); |
350 | + if (pos === 0) { |
351 | + list.prepend(option); |
352 | + } |
353 | + else { |
354 | + list.insertBefore(option, options.item(pos)); |
355 | + } |
356 | + } |
357 | + } |
358 | + }, this |
359 | + ); |
360 | + Y.lazr.anim.green_flash({node: this.fieldNode}).run(); |
361 | + } |
362 | + |
363 | +}); |
364 | + |
365 | + |
366 | +namespace.ChoiceListWidget = ChoiceListWidget; |
367 | + |
368 | + |
369 | +/** |
370 | + * A special form of FormRowWidget, containing a select control. |
371 | + * |
372 | + * @class SelectWidget |
373 | + */ |
374 | +var SelectWidget; |
375 | + |
376 | +SelectWidget = function() { |
377 | + SelectWidget.superclass.constructor.apply(this, arguments); |
378 | +}; |
379 | + |
380 | +Y.mix(SelectWidget, { |
381 | + |
382 | + NAME: 'selectWidget', |
383 | + |
384 | + ATTRS: { |
385 | + |
386 | + /** |
387 | + * An array of objects from which to choose. Each object |
388 | + * should contain a value for "value", "text" and "data". |
389 | + * |
390 | + * @property choices |
391 | + */ |
392 | + choices: { |
393 | + getter: function() { |
394 | + /* I think this is a YUI3 wart; I can't see any way to |
395 | + map() over a NodeList, so I must push the elements |
396 | + one by one into an array first. */ |
397 | + var options = Y.Array([]); |
398 | + this.fieldNode.all("select > option").each( |
399 | + function(option) { options.push(option); }); |
400 | + return options.map( |
401 | + function(option) { |
402 | + return { |
403 | + value: option.get("value"), |
404 | + text: option.get("text"), |
405 | + data: option.getData("data") |
406 | + }; |
407 | + } |
408 | + ); |
409 | + }, |
410 | + setter: function(value, name) { |
411 | + var select = Y.Node.create("<select />"); |
412 | + select.set("name", this.get("name")) |
413 | + .set("size", this.get("size")); |
414 | + if (this.get("multiple")) { |
415 | + select.set("multiple", "multiple"); |
416 | + } |
417 | + var choices = Y.Array(value); |
418 | + choices.forEach( |
419 | + function(choice) { |
420 | + var option = Y.Node.create("<option />"); |
421 | + option.set("value", choice.value) |
422 | + .set("text", choice.text) |
423 | + .setData("data", choice.data); |
424 | + select.append(option); |
425 | + } |
426 | + ); |
427 | + if (choices.length > 0) { |
428 | + this.fieldNode.empty().append(select); |
429 | + } |
430 | + else { |
431 | + this.fieldNode.empty(); |
432 | + } |
433 | + } |
434 | + }, |
435 | + |
436 | + /** |
437 | + * The current selection. |
438 | + * |
439 | + * @property choice |
440 | + */ |
441 | + choice: { |
442 | + setter: function(value, name) { |
443 | + if (!Y.Lang.isArray(value)) { |
444 | + value = [value]; |
445 | + } |
446 | + this.fieldNode.all("select > option").each( |
447 | + function(node) { |
448 | + node.set( |
449 | + "selected", |
450 | + value.indexOf(node.get("value")) >= 0); |
451 | + } |
452 | + ); |
453 | + }, |
454 | + getter: function() { |
455 | + var choice = []; |
456 | + this.fieldNode.all("select > option").each( |
457 | + function(node) { |
458 | + if (node.get("selected")) { |
459 | + choice.push(node.get("value")); |
460 | + } |
461 | + } |
462 | + ); |
463 | + return choice; |
464 | + } |
465 | + }, |
466 | + |
467 | + /** |
468 | + * The number of rows to show in the select widget. |
469 | + * |
470 | + * @property size |
471 | + */ |
472 | + size: { |
473 | + value: 1, |
474 | + setter: function(value, name) { |
475 | + this.fieldNode.all("select").set("size", value); |
476 | + } |
477 | + }, |
478 | + |
479 | + /** |
480 | + * Whether multiple rows can be selected. |
481 | + * |
482 | + * @property multiple |
483 | + */ |
484 | + multiple: { |
485 | + value: false, |
486 | + setter: function(value, name) { |
487 | + value = value ? true : false; |
488 | + this.fieldNode.all("select").set("multiple", value); |
489 | + return value; |
490 | + } |
491 | + } |
492 | + |
493 | + } |
494 | + |
495 | +}); |
496 | + |
497 | +Y.extend(SelectWidget, FormRowWidget, { |
498 | + |
499 | + _sorted_position: function(choice) { |
500 | + var options = []; |
501 | + this.fieldNode.all("option").each( |
502 | + function(node) { |
503 | + options.push(node.get('text')); |
504 | + } |
505 | + ); |
506 | + options.push(choice); |
507 | + return options.sort().indexOf(choice); |
508 | + }, |
509 | + |
510 | + /** |
511 | + * Choose a size for the select control based on the number of |
512 | + * choices, up to an optional maximum size. |
513 | + * |
514 | + * @method autoSize |
515 | + */ |
516 | + autoSize: function(maxSize) { |
517 | + var choiceCount = this.fieldNode.all("select > option").size(); |
518 | + if (choiceCount === 0) { |
519 | + this.set("size", 1); |
520 | + } |
521 | + else if (maxSize === undefined) { |
522 | + this.set("size", choiceCount); |
523 | + } |
524 | + else if (choiceCount < maxSize) { |
525 | + this.set("size", choiceCount); |
526 | + } |
527 | + else { |
528 | + this.set("size", maxSize); |
529 | + } |
530 | + return this; |
531 | + } |
532 | + |
533 | +}); |
534 | + |
535 | +namespace.SelectWidget = SelectWidget; |
536 | + |
537 | + |
538 | +/** |
539 | + * A widget to encapsulate functionality around the form actions. |
540 | + * |
541 | + * @class FormActionsWidget |
542 | + */ |
543 | +var FormActionsWidget; |
544 | + |
545 | +FormActionsWidget = function() { |
546 | + FormActionsWidget |
547 | + .superclass.constructor.apply(this, arguments); |
548 | +}; |
549 | + |
550 | +FormActionsWidget.ATTRS = { |
551 | + duration: { |
552 | + value: 1.0 |
553 | + }, |
554 | + |
555 | + height: { |
556 | + value: 0 |
557 | + }, |
558 | + |
559 | + opacity: { |
560 | + value: 0 |
561 | + } |
562 | +}; |
563 | + |
564 | + |
565 | +Y.mix(FormActionsWidget, { |
566 | + |
567 | + NAME: 'formActionsWidget', |
568 | + |
569 | + HTML_PARSER: { |
570 | + submitButtonNode: "input[type=submit]" |
571 | + } |
572 | + |
573 | +}); |
574 | + |
575 | +Y.extend(FormActionsWidget, Y.Widget, { |
576 | + |
577 | + initializer: function(config) { |
578 | + this.client = new Y.lp.client.Launchpad(); |
579 | + this.error_handler = new Y.lp.client.ErrorHandler(); |
580 | + this.error_handler.clearProgressUI = Y.bind(this.hideSpinner, this); |
581 | + this.error_handler.showError = Y.bind(this.showError, this); |
582 | + this.submitButtonNode = config.submitButtonNode; |
583 | + this.spinnerNode = Y.Node.create( |
584 | + '<img src="/@@/spinner" alt="Loading..." />'); |
585 | + }, |
586 | + |
587 | + /** |
588 | + * Show the spinner, and hide the submit button. |
589 | + * |
590 | + * @method showSpinner |
591 | + */ |
592 | + showSpinner: function() { |
593 | + this.submitButtonNode.replace(this.spinnerNode); |
594 | + }, |
595 | + |
596 | + /** |
597 | + * Hide the spinner, and show the submit button again. |
598 | + * |
599 | + * @method hideSpinner |
600 | + */ |
601 | + hideSpinner: function() { |
602 | + this.spinnerNode.replace(this.submitButtonNode); |
603 | + }, |
604 | + |
605 | + /** |
606 | + * Display an error. |
607 | + * |
608 | + * @method showError |
609 | + */ |
610 | + showError: function(error) { |
611 | + Y.Node.create('<p class="error message" />') |
612 | + .appendTo(this.get("contentBox")) |
613 | + .set("text", error); |
614 | + }, |
615 | + |
616 | + /** |
617 | + * Remove all errors that have been previously displayed by showError. |
618 | + * |
619 | + * @method hideErrors |
620 | + */ |
621 | + hideErrors: function(error) { |
622 | + this.get("contentBox").all("p.error.message").remove(); |
623 | + } |
624 | + |
625 | +}); |
626 | + |
627 | +namespace.FormActionsWidget = FormActionsWidget; |
628 | + |
629 | + |
630 | +}, "0.1", {"requires": ["node", "dom", "io", "widget", "lp.client", |
631 | + "lazr.anim", "array-extras", "transition"]}); |
632 | |
633 | === added directory 'lib/lp/app/javascript/formwidgets/tests' |
634 | === added file 'lib/lp/app/javascript/formwidgets/tests/test_formwidgets.html' |
635 | --- lib/lp/app/javascript/formwidgets/tests/test_formwidgets.html 1970-01-01 00:00:00 +0000 |
636 | +++ lib/lp/app/javascript/formwidgets/tests/test_formwidgets.html 2011-07-18 11:56:36 +0000 |
637 | @@ -0,0 +1,47 @@ |
638 | +<!DOCTYPE |
639 | + HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" |
640 | + "http://www.w3.org/TR/html4/strict.dtd"> |
641 | +<html> |
642 | + <head> |
643 | + <title>Launchpad Form Widgets</title> |
644 | + |
645 | + <!-- YUI and test setup --> |
646 | + <link rel="stylesheet" href="../../testing/test.css" /> |
647 | + <script type="text/javascript" |
648 | + src="../../../../../canonical/launchpad/icing/yui/yui/yui.js"></script> |
649 | + <script type="text/javascript" |
650 | + src="../../testing/testrunner.js"></script> |
651 | + |
652 | + <!-- Required modules --> |
653 | + <script type="text/javascript" |
654 | + src="../../client.js"></script> |
655 | + <script type="text/javascript" |
656 | + src="../../activator/activator.js"></script> |
657 | + <script type="text/javascript" |
658 | + src="../../anim/anim.js"></script> |
659 | + <script type="text/javascript" |
660 | + src="../../lazr/lazr.js"></script> |
661 | + <script type="text/javascript" |
662 | + src="../../overlay/overlay.js"></script> |
663 | + <!-- <script type="text/javascript" --> |
664 | + <!-- src="../../picker/picker.js"></script> --> |
665 | + <!-- <script type="text/javascript" --> |
666 | + <!-- src="../../picker/person_picker.js"></script> --> |
667 | + <!-- <script type="text/javascript" --> |
668 | + <!-- src="../../picker/picker_patcher.js"></script> --> |
669 | + |
670 | + <!-- The module under test --> |
671 | + <script type="text/javascript" |
672 | + src="../formwidgets.js"></script> |
673 | + |
674 | + <!-- The test suite --> |
675 | + <script type="text/javascript" |
676 | + src="test_formwidgets.js"></script> |
677 | + |
678 | + </head> |
679 | + <body class="yui3-skin-sam"> |
680 | + <ul id="suites"> |
681 | + <li>lp.app.formwidgets.test</li> |
682 | + </ul> |
683 | + </body> |
684 | +</html> |
685 | |
686 | === added file 'lib/lp/app/javascript/formwidgets/tests/test_formwidgets.js' |
687 | --- lib/lp/app/javascript/formwidgets/tests/test_formwidgets.js 1970-01-01 00:00:00 +0000 |
688 | +++ lib/lp/app/javascript/formwidgets/tests/test_formwidgets.js 2011-07-18 11:56:36 +0000 |
689 | @@ -0,0 +1,605 @@ |
690 | +/** |
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 | + * Tests for Form Widgets. |
695 | + * |
696 | + * @module lp.app.formwidgets |
697 | + * @submodule test |
698 | + */ |
699 | + |
700 | +YUI.add('lp.app.formwidgets.test', function(Y) { |
701 | + |
702 | + var namespace = Y.namespace('lp.app.formwidgets.test'); |
703 | + |
704 | + var Assert = Y.Assert; |
705 | + var ArrayAssert = Y.ArrayAssert; |
706 | + |
707 | + var suite = new Y.Test.Suite("formwidgets Tests"); |
708 | + var widgets = Y.lp.app.formwidgets; |
709 | + |
710 | + var attrgetter = function(name) { |
711 | + return function(thing) { |
712 | + return thing[name]; |
713 | + }; |
714 | + }; |
715 | + |
716 | + var attrselect = function(name) { |
717 | + return function(things) { |
718 | + return Y.Array(things).map(attrgetter(name)); |
719 | + }; |
720 | + }; |
721 | + |
722 | + var testFormRowWidget = { |
723 | + name: 'TestFormRowWidget', |
724 | + |
725 | + setUp: function() { |
726 | + this.container = Y.Node.create("<div />"); |
727 | + this.widget = new widgets.FormRowWidget(); |
728 | + }, |
729 | + |
730 | + tearDown: function() { |
731 | + this.container.remove(true); |
732 | + }, |
733 | + |
734 | + testRender: function() { |
735 | + this.widget.render(this.container); |
736 | + Assert.isTrue( |
737 | + this.container.contains( |
738 | + this.widget.get("boundingBox"))); |
739 | + }, |
740 | + |
741 | + testRenderWithName: function() { |
742 | + this.widget.fieldNode.append( |
743 | + Y.Node.create("<input /><input />")); |
744 | + this.widget.set("name", "field"); |
745 | + this.widget.render(this.container); |
746 | + ArrayAssert.itemsAreEqual( |
747 | + ["field", "field"], |
748 | + this.container.all("input").get("name")); |
749 | + }, |
750 | + |
751 | + testRenderWithNameChange: function() { |
752 | + this.widget.fieldNode.append( |
753 | + Y.Node.create("<input /><input />")); |
754 | + this.widget.set("name", "field"); |
755 | + this.widget.render(this.container); |
756 | + this.widget.set("name", "plain"); |
757 | + ArrayAssert.itemsAreEqual( |
758 | + ["plain", "plain"], |
759 | + this.container.all("input").get("name")); |
760 | + }, |
761 | + |
762 | + testRenderLabel: function() { |
763 | + this.widget.set("label", "Test label"); |
764 | + this.widget.render(this.container); |
765 | + Assert.areEqual( |
766 | + "Test label", |
767 | + this.container.one("label").get("text")); |
768 | + }, |
769 | + |
770 | + testRenderLabelChange: function() { |
771 | + this.widget.set("label", "Test label"); |
772 | + this.widget.render(this.container); |
773 | + this.widget.set("label", "Another label"); |
774 | + Assert.areEqual( |
775 | + "Another label", |
776 | + this.container.one("label").get("text")); |
777 | + }, |
778 | + |
779 | + testRenderDescription: function() { |
780 | + this.widget.set("description", "Test description."); |
781 | + this.widget.render(this.container); |
782 | + Assert.areEqual( |
783 | + "Test description.", |
784 | + this.container.one("p.formHelp").get("text")); |
785 | + }, |
786 | + |
787 | + testRenderDescriptionChange: function() { |
788 | + this.widget.set("description", "Test description."); |
789 | + this.widget.render(this.container); |
790 | + this.widget.set("description", "Another description."); |
791 | + Assert.areEqual( |
792 | + "Another description.", |
793 | + this.container.one("p.formHelp").get("text")); |
794 | + }, |
795 | + |
796 | + testRenderHelp: function() { |
797 | + this.widget.set("help", |
798 | + {link: "http://test.com/test.html", text: "Help text"}); |
799 | + this.widget.render(this.container); |
800 | + Assert.isFalse(this.container |
801 | + .one('span.helper').hasClass("unseen")); |
802 | + Assert.areEqual( |
803 | + "Help text", |
804 | + this.container.one("a") |
805 | + .one('span.invisible-link').get("text")); |
806 | + Assert.areEqual( |
807 | + "http://test.com/test.html", |
808 | + this.container.one("a").get('href')); |
809 | + }, |
810 | + |
811 | + testGetHelp: function() { |
812 | + this.widget.set("help", |
813 | + {link: "http://test.com/test.html", text: "Help text"}); |
814 | + this.widget.render(this.container); |
815 | + Assert.areEqual( |
816 | + "http://test.com/test.html", |
817 | + this.widget.get("help").link); |
818 | + Assert.areEqual( |
819 | + "Help text", |
820 | + this.widget.get("help").text); |
821 | + }, |
822 | + |
823 | + testChangeHelp: function() { |
824 | + this.widget.set("help", |
825 | + {link: "http://test.com/test.html", text: "Help text"}); |
826 | + this.widget.render(this.container); |
827 | + this.widget.set( |
828 | + "help", |
829 | + {link: "http://test.com/test2.html", text: "Help text2"}); |
830 | + Assert.areEqual( |
831 | + "Help text2", |
832 | + this.container.one("a") |
833 | + .one('span.invisible-link').get("text")); |
834 | + Assert.areEqual( |
835 | + "http://test.com/test2.html", |
836 | + this.container.one("a").get('href')); |
837 | + }, |
838 | + |
839 | + testChangeHelpUndefined: function() { |
840 | + this.widget.set("help", |
841 | + {link: "http://test.com/test.html", text: "Help text"}); |
842 | + this.widget.render(this.container); |
843 | + this.widget.set("help", {}); |
844 | + Assert.isTrue(this.container |
845 | + .one('span.helper').hasClass("unseen")); |
846 | + }, |
847 | + |
848 | + testSpinner: function() { |
849 | + Assert.isFalse( |
850 | + this.widget.fieldNode.contains(this.widget.spinnerNode)); |
851 | + this.widget.showSpinner(); |
852 | + Assert.isTrue( |
853 | + this.widget.fieldNode.contains(this.widget.spinnerNode)); |
854 | + this.widget.hideSpinner(); |
855 | + Assert.isFalse( |
856 | + this.widget.fieldNode.contains(this.widget.spinnerNode)); |
857 | + }, |
858 | + |
859 | + testShowError: function() { |
860 | + this.widget.showError("Unrealistic expectations."); |
861 | + Assert.areEqual( |
862 | + "Unrealistic expectations.", |
863 | + this.widget.fieldNode.one("p").get("text")); |
864 | + } |
865 | + |
866 | + }; |
867 | + |
868 | + suite.add(new Y.Test.Case(testFormRowWidget)); |
869 | + |
870 | + var testChoiceListWidget = { |
871 | + name: 'TestChoiceListWidget', |
872 | + |
873 | + setUp: function() { |
874 | + this.container = Y.Node.create("<div />"); |
875 | + this.widget = new widgets.ChoiceListWidget(); |
876 | + }, |
877 | + |
878 | + tearDown: function() { |
879 | + this.container.remove(true); |
880 | + }, |
881 | + |
882 | + testRenderChoices: function() { |
883 | + this.widget.set("choices", ["a", "b"]); |
884 | + this.widget.render(this.container); |
885 | + ArrayAssert.itemsAreEqual( |
886 | + ["a", "b"], |
887 | + this.container.all("li > input").get("value")); |
888 | + ArrayAssert.itemsAreEqual( |
889 | + ["a", "b"], |
890 | + this.container.all("li > label").get("text")); |
891 | + ArrayAssert.itemsAreEqual( |
892 | + ["checkbox", "checkbox"], |
893 | + this.container.all("li > input").getAttribute("type")); |
894 | + }, |
895 | + |
896 | + testRenderChoicesChange: function() { |
897 | + this.widget.set("choices", ["a", "b"]); |
898 | + this.widget.render(this.container); |
899 | + this.widget.set("choices", ["c", "d", "e"]); |
900 | + ArrayAssert.itemsAreEqual( |
901 | + ["c", "d", "e"], |
902 | + this.container.all("li > input").get("value")); |
903 | + ArrayAssert.itemsAreEqual( |
904 | + ["c", "d", "e"], |
905 | + this.container.all("li > label").get("text")); |
906 | + }, |
907 | + |
908 | + testRenderAddChoices: function() { |
909 | + this.widget.add_choices(["a", "b"]); |
910 | + this.widget.render(this.container); |
911 | + ArrayAssert.itemsAreEqual( |
912 | + ["a", "b"], |
913 | + this.container.all("li > input").get("value")); |
914 | + ArrayAssert.itemsAreEqual( |
915 | + ["a", "b"], |
916 | + this.container.all("li > label").get("text")); |
917 | + ArrayAssert.itemsAreEqual( |
918 | + ["checkbox", "checkbox"], |
919 | + this.container.all("li > input").getAttribute("type")); |
920 | + }, |
921 | + |
922 | + testRenderRemoveChoices: function() { |
923 | + this.widget.add_choices(["a", "b", "c", "d"]); |
924 | + this.widget.render(this.container); |
925 | + this.widget.remove_choices(["b", "d"]); |
926 | + ArrayAssert.itemsAreEqual( |
927 | + ["a", "c"], |
928 | + this.container.all("li > input").get("value")); |
929 | + ArrayAssert.itemsAreEqual( |
930 | + ["a", "c"], |
931 | + this.container.all("li > label").get("text")); |
932 | + }, |
933 | + |
934 | + testRenderChoicesChangeType: function() { |
935 | + this.widget.set("choices", ["a", "b"]); |
936 | + this.widget.render(this.container); |
937 | + this.widget.set("type", "radio"); |
938 | + ArrayAssert.itemsAreEqual( |
939 | + ["radio", "radio"], |
940 | + this.container.all("li > input").getAttribute("type")); |
941 | + |
942 | + }, |
943 | + |
944 | + testChoiceWithCheckBox: function() { |
945 | + this.widget |
946 | + .set("type", "checkbox") |
947 | + .set("choices", ["a", "b"]); |
948 | + ArrayAssert.itemsAreEqual( |
949 | + [], this.widget.get("choice")); |
950 | + this.widget.fieldNode.one("input[value=a]") |
951 | + .set("checked", "checked"); |
952 | + ArrayAssert.itemsAreEqual( |
953 | + ["a"], this.widget.get("choice")); |
954 | + }, |
955 | + |
956 | + testChoiceWithRadio: function() { |
957 | + // When both radio buttons are checked (this is possible in some |
958 | + // broken DOMs/JS engined), choice is undefined. |
959 | + this.widget |
960 | + .set("type", "radio") |
961 | + .set("choices", ["a", "b"]); |
962 | + Assert.isNull(this.widget.get("choice")); |
963 | + this.widget.fieldNode.one("input[value=a]") |
964 | + .set("checked", "checked"); |
965 | + Assert.areEqual("a", this.widget.get("choice")); |
966 | + this.widget.fieldNode.one("input[value=b]") |
967 | + .set("checked", "checked"); |
968 | + if (this.widget.fieldNode.one("input[value=a]").get("checked")) { |
969 | + // This assertion can only be made if the DOM/JS is broken |
970 | + // in the host browser. |
971 | + Assert.isUndefined(this.widget.get("choice")); |
972 | + } |
973 | + else { |
974 | + // The host browser's DOM/JS is sane. |
975 | + ArrayAssert.itemsAreEqual( |
976 | + ["b"], this.widget.get("choice")); |
977 | + } |
978 | + }, |
979 | + |
980 | + testSetChoiceWithCheckBox: function() { |
981 | + this.widget |
982 | + .set("type", "checkbox") |
983 | + .set("choices", ["a", "b"]) |
984 | + .set("choice", "a"); |
985 | + ArrayAssert.itemsAreEqual( |
986 | + ["a"], this.widget.get("choice")); |
987 | + this.widget.set("choice", ["a"]); |
988 | + ArrayAssert.itemsAreEqual( |
989 | + ["a"], this.widget.get("choice")); |
990 | + this.widget.set("choice", ["a", "b"]); |
991 | + ArrayAssert.itemsAreEqual( |
992 | + ["a", "b"], this.widget.get("choice")); |
993 | + this.widget.set("choice", ["b", "c"]); |
994 | + ArrayAssert.itemsAreEqual( |
995 | + ["b"], this.widget.get("choice")); |
996 | + }, |
997 | + |
998 | + testSetChoiceWithRadio: function() { |
999 | + this.widget |
1000 | + .set("type", "radio") |
1001 | + .set("choices", ["a", "b"]) |
1002 | + .set("choice", "a"); |
1003 | + ArrayAssert.itemsAreEqual( |
1004 | + "a", this.widget.get("choice")); |
1005 | + this.widget.set("choice", ["a"]); |
1006 | + ArrayAssert.itemsAreEqual( |
1007 | + "a", this.widget.get("choice")); |
1008 | + this.widget.set("choice", "b"); |
1009 | + ArrayAssert.itemsAreEqual( |
1010 | + "b", this.widget.get("choice")); |
1011 | + } |
1012 | + |
1013 | + }; |
1014 | + |
1015 | + testChoiceListWidget = Y.merge( |
1016 | + testFormRowWidget, testChoiceListWidget); |
1017 | + suite.add(new Y.Test.Case(testChoiceListWidget)); |
1018 | + |
1019 | + var testSelectWidget = { |
1020 | + name: 'TestSelectWidget', |
1021 | + |
1022 | + choices: [ |
1023 | + {value: "a", text: "A", data: 123}, |
1024 | + {value: "b", text: "B", data: 456}, |
1025 | + {value: "c", text: "C", data: 789} |
1026 | + ], |
1027 | + |
1028 | + setUp: function() { |
1029 | + this.container = Y.Node.create("<div />"); |
1030 | + this.widget = new widgets.SelectWidget(); |
1031 | + }, |
1032 | + |
1033 | + tearDown: function() { |
1034 | + this.container.remove(true); |
1035 | + }, |
1036 | + |
1037 | + testNameChange: function() { |
1038 | + this.widget |
1039 | + .set("name", "foo") |
1040 | + .set("choices", this.choices); |
1041 | + var select = this.widget.fieldNode.one("select"); |
1042 | + Assert.areEqual("foo", select.get("name")); |
1043 | + this.widget |
1044 | + .set("name", "bar"); |
1045 | + Assert.areEqual("bar", select.get("name")); |
1046 | + }, |
1047 | + |
1048 | + testChoices: function() { |
1049 | + this.widget.set("choices", this.choices); |
1050 | + var choices_observed = this.widget.get("choices"); |
1051 | + /* We have to compare bit by bit ourselves because |
1052 | + Javascript is a language born in hell. */ |
1053 | + ArrayAssert.itemsAreEqual( |
1054 | + attrselect("value")(this.choices), |
1055 | + attrselect("value")(choices_observed)); |
1056 | + ArrayAssert.itemsAreEqual( |
1057 | + attrselect("text")(this.choices), |
1058 | + attrselect("text")(choices_observed)); |
1059 | + ArrayAssert.itemsAreEqual( |
1060 | + attrselect("data")(this.choices), |
1061 | + attrselect("data")(choices_observed)); |
1062 | + }, |
1063 | + |
1064 | + testRenderChoices: function() { |
1065 | + this.widget.set("choices", this.choices); |
1066 | + this.widget.render(this.container); |
1067 | + ArrayAssert.itemsAreEqual( |
1068 | + ["a", "b", "c"], |
1069 | + this.container.all("select > option").get("value")); |
1070 | + ArrayAssert.itemsAreEqual( |
1071 | + ["A", "B", "C"], |
1072 | + this.container.all("select > option").get("text")); |
1073 | + }, |
1074 | + |
1075 | + testRenderEmptyChoices: function() { |
1076 | + this.widget.fieldNode.append("something"); |
1077 | + this.widget.set("choices", []); |
1078 | + this.widget.render(this.container); |
1079 | + Assert.isNull(this.container.one("select")); |
1080 | + Assert.isFalse(this.widget.fieldNode.hasChildNodes()); |
1081 | + }, |
1082 | + |
1083 | + testRenderChoicesChange: function() { |
1084 | + var choices1 = [ |
1085 | + {value: "a", text: "A", data: 123} |
1086 | + ]; |
1087 | + this.widget.set("choices", choices1); |
1088 | + this.widget.render(this.container); |
1089 | + var choices2 = [ |
1090 | + {value: "b", text: "B", data: 456}, |
1091 | + {value: "c", text: "C", data: 789} |
1092 | + ]; |
1093 | + this.widget.set("choices", choices2); |
1094 | + ArrayAssert.itemsAreEqual( |
1095 | + ["b", "c"], |
1096 | + this.container.all("select > option").get("value")); |
1097 | + ArrayAssert.itemsAreEqual( |
1098 | + ["B", "C"], |
1099 | + this.container.all("select > option").get("text")); |
1100 | + }, |
1101 | + |
1102 | + testChoice: function() { |
1103 | + this.widget |
1104 | + .set("choices", this.choices) |
1105 | + .set("multiple", true); |
1106 | + /* It would be better to deselect all options by default, |
1107 | + but this appears impossible; the browser seems to |
1108 | + select the first option when rendering. */ |
1109 | + this.widget.fieldNode.all("option").set("selected", false); |
1110 | + ArrayAssert.itemsAreEqual( |
1111 | + [], this.widget.get("choice")); |
1112 | + this.widget.fieldNode.one("option[value=a]") |
1113 | + .set("selected", true); |
1114 | + ArrayAssert.itemsAreEqual( |
1115 | + ["a"], this.widget.get("choice")); |
1116 | + this.widget.fieldNode.one("option[value=c]") |
1117 | + .set("selected", true); |
1118 | + ArrayAssert.itemsAreEqual( |
1119 | + ["a", "c"], this.widget.get("choice")); |
1120 | + }, |
1121 | + |
1122 | + testSetChoice: function() { |
1123 | + this.widget |
1124 | + .set("multiple", true) |
1125 | + .set("choices", this.choices) |
1126 | + .set("choice", "a"); |
1127 | + ArrayAssert.itemsAreEqual( |
1128 | + ["a"], this.widget.get("choice")); |
1129 | + this.widget.set("choice", ["a"]); |
1130 | + ArrayAssert.itemsAreEqual( |
1131 | + ["a"], this.widget.get("choice")); |
1132 | + this.widget.set("choice", ["a", "b"]); |
1133 | + ArrayAssert.itemsAreEqual( |
1134 | + ["a", "b"], this.widget.get("choice")); |
1135 | + this.widget.set("choice", ["b", "z"]); |
1136 | + ArrayAssert.itemsAreEqual( |
1137 | + ["b"], this.widget.get("choice")); |
1138 | + }, |
1139 | + |
1140 | + testSize: function() { |
1141 | + Assert.areEqual(1, this.widget.get("size")); |
1142 | + }, |
1143 | + |
1144 | + testRenderSize: function() { |
1145 | + this.widget |
1146 | + .set("choices", this.choices) |
1147 | + .set("size", 7) |
1148 | + .render(this.container); |
1149 | + Assert.areEqual( |
1150 | + 7, this.widget.fieldNode.one("select").get("size")); |
1151 | + }, |
1152 | + |
1153 | + testRenderSizeChange: function() { |
1154 | + this.widget |
1155 | + .set("choices", this.choices) |
1156 | + .set("size", 3) |
1157 | + .render(this.container) |
1158 | + .set("size", 5); |
1159 | + Assert.areEqual( |
1160 | + 5, this.widget.fieldNode.one("select").get("size")); |
1161 | + }, |
1162 | + |
1163 | + testAutoSize: function() { |
1164 | + this.widget.set("choices", this.choices); |
1165 | + /* Without argument, autoSize() sets the size to the same |
1166 | + as the number of choices. */ |
1167 | + this.widget.autoSize(); |
1168 | + Assert.areEqual(3, this.widget.get("size")); |
1169 | + }, |
1170 | + |
1171 | + testAutoSizeMoreChoicesThanMaxiumum: function() { |
1172 | + this.widget.set("choices", this.choices); |
1173 | + /* autoSize() sets the size to the same as the number of |
1174 | + choices unless there are more than the specified |
1175 | + maximum. */ |
1176 | + this.widget.autoSize(2); |
1177 | + Assert.areEqual(2, this.widget.get("size")); |
1178 | + }, |
1179 | + |
1180 | + testAutoSizeFewerChoicesThanMaxiumum: function() { |
1181 | + this.widget.set("choices", this.choices); |
1182 | + /* autoSize() sets the size to the same as the number of |
1183 | + choices. */ |
1184 | + this.widget.autoSize(5); |
1185 | + Assert.areEqual(3, this.widget.get("size")); |
1186 | + }, |
1187 | + |
1188 | + testMultiple: function() { |
1189 | + Assert.areEqual(false, this.widget.get("multiple")); |
1190 | + }, |
1191 | + |
1192 | + testRenderMultiple: function() { |
1193 | + this.widget |
1194 | + .set("choices", this.choices) |
1195 | + .set("multiple", true) |
1196 | + .render(this.container); |
1197 | + Assert.isTrue( |
1198 | + this.widget.fieldNode.one("select") |
1199 | + .hasAttribute("multiple")); |
1200 | + }, |
1201 | + |
1202 | + testRenderMultipleChange: function() { |
1203 | + this.widget |
1204 | + .set("choices", this.choices) |
1205 | + .set("multiple", true) |
1206 | + .render(this.container) |
1207 | + .set("multiple", false); |
1208 | + Assert.isFalse( |
1209 | + this.widget.fieldNode.one("select") |
1210 | + .hasAttribute("multiple")); |
1211 | + } |
1212 | + |
1213 | + }; |
1214 | + |
1215 | + testSelectWidget = Y.merge( |
1216 | + testFormRowWidget, testSelectWidget); |
1217 | + suite.add(new Y.Test.Case(testSelectWidget)); |
1218 | + |
1219 | + var testFormActionsWidget = { |
1220 | + name: 'TestFormActionsWidget', |
1221 | + |
1222 | + makeActionsDiv: function() { |
1223 | + var submit = Y.Node.create("<input />") |
1224 | + .set("type", "submit") |
1225 | + .set("value", "Initialize Series"); |
1226 | + var cancel = Y.Node.create("<a>Cancel</a>"); |
1227 | + var div = Y.Node.create("<div />") |
1228 | + .addClass("actions") |
1229 | + .append(submit) |
1230 | + .append(cancel); |
1231 | + return div; |
1232 | + }, |
1233 | + |
1234 | + setUp: function() { |
1235 | + this.actions = this.makeActionsDiv(); |
1236 | + this.widget = new widgets.FormActionsWidget( |
1237 | + {srcNode: this.actions}); |
1238 | + }, |
1239 | + |
1240 | + tearDown: function() { |
1241 | + this.actions.remove(true); |
1242 | + }, |
1243 | + |
1244 | + testInitializer: function() { |
1245 | + Assert.isTrue( |
1246 | + this.actions.one("input").compareTo( |
1247 | + this.widget.submitButtonNode)); |
1248 | + }, |
1249 | + |
1250 | + testSpinner: function() { |
1251 | + Assert.isTrue( |
1252 | + this.actions.contains(this.widget.submitButtonNode)); |
1253 | + Assert.isFalse( |
1254 | + this.actions.contains(this.widget.spinnerNode)); |
1255 | + this.widget.showSpinner(); |
1256 | + Assert.isFalse( |
1257 | + this.actions.contains(this.widget.submitButtonNode)); |
1258 | + Assert.isTrue( |
1259 | + this.actions.contains(this.widget.spinnerNode)); |
1260 | + this.widget.hideSpinner(); |
1261 | + Assert.isTrue( |
1262 | + this.actions.contains(this.widget.submitButtonNode)); |
1263 | + Assert.isFalse( |
1264 | + this.actions.contains(this.widget.spinnerNode)); |
1265 | + }, |
1266 | + |
1267 | + testShowError: function() { |
1268 | + this.widget.showError("The Man From U.N.C.L.E."); |
1269 | + Assert.areEqual( |
1270 | + "The Man From U.N.C.L.E.", |
1271 | + this.actions.one("p.error.message").get("text")); |
1272 | + }, |
1273 | + |
1274 | + testHideErrors: function() { |
1275 | + this.widget.showError("The Man From U.N.C.L.E."); |
1276 | + this.widget.showError("The Woman From A.U.N.T.I.E."); |
1277 | + this.widget.hideErrors(); |
1278 | + Assert.isNull(this.actions.one("p.error.message")); |
1279 | + } |
1280 | + |
1281 | + }; |
1282 | + |
1283 | + suite.add(new Y.Test.Case(testFormActionsWidget)); |
1284 | + |
1285 | + // Exports. |
1286 | + namespace.testFormRowWidget = testFormRowWidget; |
1287 | + namespace.testChoiceListWidget = testChoiceListWidget; |
1288 | + namespace.testSelectWidget = testSelectWidget; |
1289 | + namespace.testFormActionsWidget = testFormActionsWidget; |
1290 | + namespace.suite = suite; |
1291 | + |
1292 | +}, "0.1", {"requires": [ |
1293 | + 'test', 'console', 'node-event-simulate', |
1294 | + 'lp.app.formwidgets']}); |
1295 | |
1296 | === added directory 'lib/lp/registry/javascript/distroseries' |
1297 | === renamed file 'lib/lp/registry/javascript/distroseries.initseries.js' => 'lib/lp/registry/javascript/distroseries/initseries.js' |
1298 | --- lib/lp/registry/javascript/distroseries.initseries.js 2011-07-18 11:56:35 +0000 |
1299 | +++ lib/lp/registry/javascript/distroseries/initseries.js 2011-07-18 11:56:36 +0000 |
1300 | @@ -2,10 +2,10 @@ |
1301 | * Copyright 2011 Canonical Ltd. This software is licensed under the |
1302 | * GNU Affero General Public License version 3 (see the file LICENSE). |
1303 | * |
1304 | - * DistroSeries related stuff. |
1305 | + * DistroSeries Initialization. |
1306 | * |
1307 | - * @module registry |
1308 | - * @submodule distroseries |
1309 | + * @module lp.registry.distroseries |
1310 | + * @submodule initseries |
1311 | */ |
1312 | |
1313 | YUI.add('lp.registry.distroseries.initseries', function(Y) { |
1314 | @@ -15,6 +15,7 @@ |
1315 | var namespace = Y.namespace('lp.registry.distroseries.initseries'); |
1316 | |
1317 | var widgets = Y.lp.registry.distroseries.widgets; |
1318 | +var formwidgets = Y.lp.app.formwidgets; |
1319 | |
1320 | |
1321 | /** |
1322 | @@ -35,7 +36,7 @@ |
1323 | |
1324 | }); |
1325 | |
1326 | -Y.extend(DeriveDistroSeriesActionsWidget, widgets.FormActionsWidget, { |
1327 | +Y.extend(DeriveDistroSeriesActionsWidget, formwidgets.FormActionsWidget, { |
1328 | |
1329 | initializer: function(config) { |
1330 | this.context = config.context; |
1331 | @@ -206,7 +207,7 @@ |
1332 | .render(form_table_body); |
1333 | } |
1334 | var package_copy_options = |
1335 | - new widgets.ChoiceListWidget() |
1336 | + new formwidgets.ChoiceListWidget() |
1337 | .set("name", "field.package_copy_options") |
1338 | .set("type", "radio") |
1339 | .set("label", "Copy options:") |
1340 | @@ -305,4 +306,4 @@ |
1341 | |
1342 | }, "0.1", {"requires": ["node", "dom", "io", "widget", "array-extras", |
1343 | "transition", "lp.registry.distroseries.widgets", |
1344 | - "lp.app.picker"]}); |
1345 | + "lp.app.formwidgets", "lp.app.picker"]}); |
1346 | |
1347 | === added directory 'lib/lp/registry/javascript/distroseries/tests' |
1348 | === renamed file 'lib/lp/registry/javascript/tests/test_distroseries.initseries.html' => 'lib/lp/registry/javascript/distroseries/tests/test_initseries.html' |
1349 | --- lib/lp/registry/javascript/tests/test_distroseries.initseries.html 2011-07-18 11:56:35 +0000 |
1350 | +++ lib/lp/registry/javascript/distroseries/tests/test_initseries.html 2011-07-18 11:56:36 +0000 |
1351 | @@ -3,46 +3,48 @@ |
1352 | "http://www.w3.org/TR/html4/strict.dtd"> |
1353 | <html> |
1354 | <head> |
1355 | - <title>Launchpad DistroSeries</title> |
1356 | + <title>Launchpad DistroSeries Initialiazation</title> |
1357 | |
1358 | <!-- YUI and test setup --> |
1359 | - <link rel="stylesheet" href="../../../app/javascript/testing/test.css" /> |
1360 | - <script type="text/javascript" |
1361 | - src="../../../../canonical/launchpad/icing/yui/yui/yui.js"></script> |
1362 | - <script type="text/javascript" |
1363 | - src="../../../app/javascript/testing/testrunner.js"></script> |
1364 | + <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" /> |
1365 | + <script type="text/javascript" |
1366 | + src="../../../../../canonical/launchpad/icing/yui/yui/yui.js"></script> |
1367 | + <script type="text/javascript" |
1368 | + src="../../../../app/javascript/testing/testrunner.js"></script> |
1369 | |
1370 | <!-- Required modules --> |
1371 | <script type="text/javascript" |
1372 | - src="../../../app/javascript/client.js"></script> |
1373 | - <script type="text/javascript" |
1374 | - src="../../../app/javascript/activator/activator.js"></script> |
1375 | - <script type="text/javascript" |
1376 | - src="../../../app/javascript/anim/anim.js"></script> |
1377 | - <script type="text/javascript" |
1378 | - src="../../../app/javascript/lazr/lazr.js"></script> |
1379 | - <script type="text/javascript" |
1380 | - src="../../../app/javascript/overlay/overlay.js"></script> |
1381 | - <script type="text/javascript" |
1382 | - src="../../../app/javascript/picker/picker.js"></script> |
1383 | - <script type="text/javascript" |
1384 | - src="../../../app/javascript/picker/person_picker.js"></script> |
1385 | - <script type="text/javascript" |
1386 | - src="../../../app/javascript/picker/picker_patcher.js"></script> |
1387 | - <script type="text/javascript" |
1388 | - src="../distroseries.widgets.js"></script> |
1389 | + src="../../../../app/javascript/client.js"></script> |
1390 | + <script type="text/javascript" |
1391 | + src="../../../../app/javascript/activator/activator.js"></script> |
1392 | + <script type="text/javascript" |
1393 | + src="../../../../app/javascript/anim/anim.js"></script> |
1394 | + <script type="text/javascript" |
1395 | + src="../../../../app/javascript/lazr/lazr.js"></script> |
1396 | + <script type="text/javascript" |
1397 | + src="../../../../app/javascript/overlay/overlay.js"></script> |
1398 | + <script type="text/javascript" |
1399 | + src="../../../../app/javascript/picker/picker.js"></script> |
1400 | + <script type="text/javascript" |
1401 | + src="../../../../app/javascript/picker/person_picker.js"></script> |
1402 | + <script type="text/javascript" |
1403 | + src="../../../../app/javascript/picker/picker_patcher.js"></script> |
1404 | + <script type="text/javascript" |
1405 | + src="../../../../app/javascript/formwidgets/formwidgets.js"></script> |
1406 | + <script type="text/javascript" |
1407 | + src="../widgets.js"></script> |
1408 | |
1409 | <!-- The module under test --> |
1410 | <script type="text/javascript" |
1411 | - src="../distroseries.initseries.js"></script> |
1412 | + src="../initseries.js"></script> |
1413 | |
1414 | <!-- Required test modules --> |
1415 | <script type="text/javascript" |
1416 | - src="test_distroseries.widgets.js"></script> |
1417 | + src="../../../../app/javascript/formwidgets/tests/test_formwidgets.js"></script> |
1418 | |
1419 | <!-- The test suite --> |
1420 | <script type="text/javascript" |
1421 | - src="test_distroseries.initseries.js"></script> |
1422 | + src="test_initseries.js"></script> |
1423 | |
1424 | </head> |
1425 | <body class="yui3-skin-sam"> |
1426 | |
1427 | === renamed file 'lib/lp/registry/javascript/tests/test_distroseries.initseries.js' => 'lib/lp/registry/javascript/distroseries/tests/test_initseries.js' |
1428 | --- lib/lp/registry/javascript/tests/test_distroseries.initseries.js 2011-07-18 11:56:35 +0000 |
1429 | +++ lib/lp/registry/javascript/distroseries/tests/test_initseries.js 2011-07-18 11:56:36 +0000 |
1430 | @@ -2,9 +2,9 @@ |
1431 | * Copyright 2011 Canonical Ltd. This software is licensed under the |
1432 | * GNU Affero General Public License version 3 (see the file LICENSE). |
1433 | * |
1434 | - * Tests for DistroSeries related stuff. |
1435 | + * Tests for DistroSeries Initialization. |
1436 | * |
1437 | - * @module lp.registry.distroseries |
1438 | + * @module lp.registry.distroseries.initseries |
1439 | * @submodule test |
1440 | */ |
1441 | |
1442 | @@ -137,7 +137,7 @@ |
1443 | }; |
1444 | |
1445 | testDeriveDistroSeriesActionsWidget = Y.merge( |
1446 | - Y.lp.registry.distroseries.widgets.test.testFormActionsWidget, |
1447 | + Y.lp.app.formwidgets.test.testFormActionsWidget, |
1448 | testDeriveDistroSeriesActionsWidget); |
1449 | suite.add(new Y.Test.Case(testDeriveDistroSeriesActionsWidget)); |
1450 | |
1451 | @@ -228,5 +228,5 @@ |
1452 | |
1453 | }, "0.1", {"requires": [ |
1454 | 'test', 'console', 'node-event-simulate', |
1455 | - 'lp.registry.distroseries.widgets.test', |
1456 | + 'lp.app.formwidgets.test', |
1457 | 'lp.registry.distroseries.initseries']}); |
1458 | |
1459 | === renamed file 'lib/lp/registry/javascript/tests/test_distroseries.widgets.html' => 'lib/lp/registry/javascript/distroseries/tests/test_widgets.html' |
1460 | --- lib/lp/registry/javascript/tests/test_distroseries.widgets.html 2011-07-18 11:56:35 +0000 |
1461 | +++ lib/lp/registry/javascript/distroseries/tests/test_widgets.html 2011-07-18 11:56:36 +0000 |
1462 | @@ -3,40 +3,46 @@ |
1463 | "http://www.w3.org/TR/html4/strict.dtd"> |
1464 | <html> |
1465 | <head> |
1466 | - <title>Launchpad DistroSeries</title> |
1467 | + <title>Launchpad DistroSeries Widgets</title> |
1468 | |
1469 | <!-- YUI and test setup --> |
1470 | - <link rel="stylesheet" href="../../../app/javascript/testing/test.css" /> |
1471 | - <script type="text/javascript" |
1472 | - src="../../../../canonical/launchpad/icing/yui/yui/yui.js"></script> |
1473 | - <script type="text/javascript" |
1474 | - src="../../../app/javascript/testing/testrunner.js"></script> |
1475 | + <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" /> |
1476 | + <script type="text/javascript" |
1477 | + src="../../../../../canonical/launchpad/icing/yui/yui/yui.js"></script> |
1478 | + <script type="text/javascript" |
1479 | + src="../../../../app/javascript/testing/testrunner.js"></script> |
1480 | |
1481 | <!-- Required modules --> |
1482 | <script type="text/javascript" |
1483 | - src="../../../app/javascript/client.js"></script> |
1484 | - <script type="text/javascript" |
1485 | - src="../../../app/javascript/activator/activator.js"></script> |
1486 | - <script type="text/javascript" |
1487 | - src="../../../app/javascript/anim/anim.js"></script> |
1488 | - <script type="text/javascript" |
1489 | - src="../../../app/javascript/lazr/lazr.js"></script> |
1490 | - <script type="text/javascript" |
1491 | - src="../../../app/javascript/overlay/overlay.js"></script> |
1492 | - <script type="text/javascript" |
1493 | - src="../../../app/javascript/picker/picker.js"></script> |
1494 | - <script type="text/javascript" |
1495 | - src="../../../app/javascript/picker/person_picker.js"></script> |
1496 | - <script type="text/javascript" |
1497 | - src="../../../app/javascript/picker/picker_patcher.js"></script> |
1498 | + src="../../../../app/javascript/client.js"></script> |
1499 | + <script type="text/javascript" |
1500 | + src="../../../../app/javascript/activator/activator.js"></script> |
1501 | + <script type="text/javascript" |
1502 | + src="../../../../app/javascript/anim/anim.js"></script> |
1503 | + <script type="text/javascript" |
1504 | + src="../../../../app/javascript/lazr/lazr.js"></script> |
1505 | + <script type="text/javascript" |
1506 | + src="../../../../app/javascript/overlay/overlay.js"></script> |
1507 | + <script type="text/javascript" |
1508 | + src="../../../../app/javascript/picker/picker.js"></script> |
1509 | + <script type="text/javascript" |
1510 | + src="../../../../app/javascript/picker/person_picker.js"></script> |
1511 | + <script type="text/javascript" |
1512 | + src="../../../../app/javascript/picker/picker_patcher.js"></script> |
1513 | + <script type="text/javascript" |
1514 | + src="../../../../app/javascript/formwidgets/formwidgets.js"></script> |
1515 | |
1516 | <!-- The module under test --> |
1517 | <script type="text/javascript" |
1518 | - src="../distroseries.widgets.js"></script> |
1519 | + src="../widgets.js"></script> |
1520 | + |
1521 | + <!-- Required test modules --> |
1522 | + <script type="text/javascript" |
1523 | + src="../../../../app/javascript/formwidgets/tests/test_formwidgets.js"></script> |
1524 | |
1525 | <!-- The test suite --> |
1526 | <script type="text/javascript" |
1527 | - src="test_distroseries.widgets.js"></script> |
1528 | + src="test_widgets.js"></script> |
1529 | |
1530 | </head> |
1531 | <body class="yui3-skin-sam"> |
1532 | |
1533 | === renamed file 'lib/lp/registry/javascript/tests/test_distroseries.widgets.js' => 'lib/lp/registry/javascript/distroseries/tests/test_widgets.js' |
1534 | --- lib/lp/registry/javascript/tests/test_distroseries.widgets.js 2011-07-18 11:56:35 +0000 |
1535 | +++ lib/lp/registry/javascript/distroseries/tests/test_widgets.js 2011-07-18 11:56:36 +0000 |
1536 | @@ -2,9 +2,9 @@ |
1537 | * Copyright 2011 Canonical Ltd. This software is licensed under the |
1538 | * GNU Affero General Public License version 3 (see the file LICENSE). |
1539 | * |
1540 | - * Tests for DistroSeries related stuff. |
1541 | + * Tests for DistroSeries Widgets. |
1542 | * |
1543 | - * @module lp.registry.distroseries |
1544 | + * @module lp.registry.distroseries.widgets |
1545 | * @submodule test |
1546 | */ |
1547 | |
1548 | @@ -17,6 +17,7 @@ |
1549 | |
1550 | var suite = new Y.Test.Suite("distroseries.widgets Tests"); |
1551 | var widgets = Y.lp.registry.distroseries.widgets; |
1552 | + var formwidgets = Y.lp.app.formwidgets; |
1553 | |
1554 | var attrgetter = function(name) { |
1555 | return function(thing) { |
1556 | @@ -30,303 +31,6 @@ |
1557 | }; |
1558 | }; |
1559 | |
1560 | - var testFormRowWidget = { |
1561 | - name: 'TestFormRowWidget', |
1562 | - |
1563 | - setUp: function() { |
1564 | - this.container = Y.Node.create("<div />"); |
1565 | - this.widget = new widgets.FormRowWidget(); |
1566 | - }, |
1567 | - |
1568 | - tearDown: function() { |
1569 | - this.container.remove(true); |
1570 | - }, |
1571 | - |
1572 | - testRender: function() { |
1573 | - this.widget.render(this.container); |
1574 | - Assert.isTrue( |
1575 | - this.container.contains( |
1576 | - this.widget.get("boundingBox"))); |
1577 | - }, |
1578 | - |
1579 | - testRenderWithName: function() { |
1580 | - this.widget.fieldNode.append( |
1581 | - Y.Node.create("<input /><input />")); |
1582 | - this.widget.set("name", "field"); |
1583 | - this.widget.render(this.container); |
1584 | - ArrayAssert.itemsAreEqual( |
1585 | - ["field", "field"], |
1586 | - this.container.all("input").get("name")); |
1587 | - }, |
1588 | - |
1589 | - testRenderWithNameChange: function() { |
1590 | - this.widget.fieldNode.append( |
1591 | - Y.Node.create("<input /><input />")); |
1592 | - this.widget.set("name", "field"); |
1593 | - this.widget.render(this.container); |
1594 | - this.widget.set("name", "plain"); |
1595 | - ArrayAssert.itemsAreEqual( |
1596 | - ["plain", "plain"], |
1597 | - this.container.all("input").get("name")); |
1598 | - }, |
1599 | - |
1600 | - testRenderLabel: function() { |
1601 | - this.widget.set("label", "Test label"); |
1602 | - this.widget.render(this.container); |
1603 | - Assert.areEqual( |
1604 | - "Test label", |
1605 | - this.container.one("label").get("text")); |
1606 | - }, |
1607 | - |
1608 | - testRenderLabelChange: function() { |
1609 | - this.widget.set("label", "Test label"); |
1610 | - this.widget.render(this.container); |
1611 | - this.widget.set("label", "Another label"); |
1612 | - Assert.areEqual( |
1613 | - "Another label", |
1614 | - this.container.one("label").get("text")); |
1615 | - }, |
1616 | - |
1617 | - testRenderDescription: function() { |
1618 | - this.widget.set("description", "Test description."); |
1619 | - this.widget.render(this.container); |
1620 | - Assert.areEqual( |
1621 | - "Test description.", |
1622 | - this.container.one("p.formHelp").get("text")); |
1623 | - }, |
1624 | - |
1625 | - testRenderDescriptionChange: function() { |
1626 | - this.widget.set("description", "Test description."); |
1627 | - this.widget.render(this.container); |
1628 | - this.widget.set("description", "Another description."); |
1629 | - Assert.areEqual( |
1630 | - "Another description.", |
1631 | - this.container.one("p.formHelp").get("text")); |
1632 | - }, |
1633 | - |
1634 | - testRenderHelp: function() { |
1635 | - this.widget.set("help", |
1636 | - {link: "http://test.com/test.html", text: "Help text"}); |
1637 | - this.widget.render(this.container); |
1638 | - Assert.isFalse(this.container |
1639 | - .one('span.helper').hasClass("unseen")); |
1640 | - Assert.areEqual( |
1641 | - "Help text", |
1642 | - this.container.one("a") |
1643 | - .one('span.invisible-link').get("text")); |
1644 | - Assert.areEqual( |
1645 | - "http://test.com/test.html", |
1646 | - this.container.one("a").get('href')); |
1647 | - }, |
1648 | - |
1649 | - testGetHelp: function() { |
1650 | - this.widget.set("help", |
1651 | - {link: "http://test.com/test.html", text: "Help text"}); |
1652 | - this.widget.render(this.container); |
1653 | - Assert.areEqual( |
1654 | - "http://test.com/test.html", |
1655 | - this.widget.get("help").link); |
1656 | - Assert.areEqual( |
1657 | - "Help text", |
1658 | - this.widget.get("help").text); |
1659 | - }, |
1660 | - |
1661 | - testChangeHelp: function() { |
1662 | - this.widget.set("help", |
1663 | - {link: "http://test.com/test.html", text: "Help text"}); |
1664 | - this.widget.render(this.container); |
1665 | - this.widget.set( |
1666 | - "help", |
1667 | - {link: "http://test.com/test2.html", text: "Help text2"}); |
1668 | - Assert.areEqual( |
1669 | - "Help text2", |
1670 | - this.container.one("a") |
1671 | - .one('span.invisible-link').get("text")); |
1672 | - Assert.areEqual( |
1673 | - "http://test.com/test2.html", |
1674 | - this.container.one("a").get('href')); |
1675 | - }, |
1676 | - |
1677 | - testChangeHelpUndefined: function() { |
1678 | - this.widget.set("help", |
1679 | - {link: "http://test.com/test.html", text: "Help text"}); |
1680 | - this.widget.render(this.container); |
1681 | - this.widget.set("help", {}); |
1682 | - Assert.isTrue(this.container |
1683 | - .one('span.helper').hasClass("unseen")); |
1684 | - }, |
1685 | - |
1686 | - testSpinner: function() { |
1687 | - Assert.isFalse( |
1688 | - this.widget.fieldNode.contains(this.widget.spinnerNode)); |
1689 | - this.widget.showSpinner(); |
1690 | - Assert.isTrue( |
1691 | - this.widget.fieldNode.contains(this.widget.spinnerNode)); |
1692 | - this.widget.hideSpinner(); |
1693 | - Assert.isFalse( |
1694 | - this.widget.fieldNode.contains(this.widget.spinnerNode)); |
1695 | - }, |
1696 | - |
1697 | - testShowError: function() { |
1698 | - this.widget.showError("Unrealistic expectations."); |
1699 | - Assert.areEqual( |
1700 | - "Unrealistic expectations.", |
1701 | - this.widget.fieldNode.one("p").get("text")); |
1702 | - } |
1703 | - |
1704 | - }; |
1705 | - |
1706 | - suite.add(new Y.Test.Case(testFormRowWidget)); |
1707 | - |
1708 | - var testChoiceListWidget = { |
1709 | - name: 'TestChoiceListWidget', |
1710 | - |
1711 | - setUp: function() { |
1712 | - this.container = Y.Node.create("<div />"); |
1713 | - this.widget = new widgets.ChoiceListWidget(); |
1714 | - }, |
1715 | - |
1716 | - tearDown: function() { |
1717 | - this.container.remove(true); |
1718 | - }, |
1719 | - |
1720 | - testRenderChoices: function() { |
1721 | - this.widget.set("choices", ["a", "b"]); |
1722 | - this.widget.render(this.container); |
1723 | - ArrayAssert.itemsAreEqual( |
1724 | - ["a", "b"], |
1725 | - this.container.all("li > input").get("value")); |
1726 | - ArrayAssert.itemsAreEqual( |
1727 | - ["a", "b"], |
1728 | - this.container.all("li > label").get("text")); |
1729 | - ArrayAssert.itemsAreEqual( |
1730 | - ["checkbox", "checkbox"], |
1731 | - this.container.all("li > input").getAttribute("type")); |
1732 | - }, |
1733 | - |
1734 | - testRenderChoicesChange: function() { |
1735 | - this.widget.set("choices", ["a", "b"]); |
1736 | - this.widget.render(this.container); |
1737 | - this.widget.set("choices", ["c", "d", "e"]); |
1738 | - ArrayAssert.itemsAreEqual( |
1739 | - ["c", "d", "e"], |
1740 | - this.container.all("li > input").get("value")); |
1741 | - ArrayAssert.itemsAreEqual( |
1742 | - ["c", "d", "e"], |
1743 | - this.container.all("li > label").get("text")); |
1744 | - }, |
1745 | - |
1746 | - testRenderAddChoices: function() { |
1747 | - this.widget.add_choices(["a", "b"]); |
1748 | - this.widget.render(this.container); |
1749 | - ArrayAssert.itemsAreEqual( |
1750 | - ["a", "b"], |
1751 | - this.container.all("li > input").get("value")); |
1752 | - ArrayAssert.itemsAreEqual( |
1753 | - ["a", "b"], |
1754 | - this.container.all("li > label").get("text")); |
1755 | - ArrayAssert.itemsAreEqual( |
1756 | - ["checkbox", "checkbox"], |
1757 | - this.container.all("li > input").getAttribute("type")); |
1758 | - }, |
1759 | - |
1760 | - testRenderRemoveChoices: function() { |
1761 | - this.widget.add_choices(["a", "b", "c", "d"]); |
1762 | - this.widget.render(this.container); |
1763 | - this.widget.remove_choices(["b", "d"]); |
1764 | - ArrayAssert.itemsAreEqual( |
1765 | - ["a", "c"], |
1766 | - this.container.all("li > input").get("value")); |
1767 | - ArrayAssert.itemsAreEqual( |
1768 | - ["a", "c"], |
1769 | - this.container.all("li > label").get("text")); |
1770 | - }, |
1771 | - |
1772 | - testRenderChoicesChangeType: function() { |
1773 | - this.widget.set("choices", ["a", "b"]); |
1774 | - this.widget.render(this.container); |
1775 | - this.widget.set("type", "radio"); |
1776 | - ArrayAssert.itemsAreEqual( |
1777 | - ["radio", "radio"], |
1778 | - this.container.all("li > input").getAttribute("type")); |
1779 | - |
1780 | - }, |
1781 | - |
1782 | - testChoiceWithCheckBox: function() { |
1783 | - this.widget |
1784 | - .set("type", "checkbox") |
1785 | - .set("choices", ["a", "b"]); |
1786 | - ArrayAssert.itemsAreEqual( |
1787 | - [], this.widget.get("choice")); |
1788 | - this.widget.fieldNode.one("input[value=a]") |
1789 | - .set("checked", "checked"); |
1790 | - ArrayAssert.itemsAreEqual( |
1791 | - ["a"], this.widget.get("choice")); |
1792 | - }, |
1793 | - |
1794 | - testChoiceWithRadio: function() { |
1795 | - // When both radio buttons are checked (this is possible in some |
1796 | - // broken DOMs/JS engined), choice is undefined. |
1797 | - this.widget |
1798 | - .set("type", "radio") |
1799 | - .set("choices", ["a", "b"]); |
1800 | - Assert.isNull(this.widget.get("choice")); |
1801 | - this.widget.fieldNode.one("input[value=a]") |
1802 | - .set("checked", "checked"); |
1803 | - Assert.areEqual("a", this.widget.get("choice")); |
1804 | - this.widget.fieldNode.one("input[value=b]") |
1805 | - .set("checked", "checked"); |
1806 | - if (this.widget.fieldNode.one("input[value=a]").get("checked")) { |
1807 | - // This assertion can only be made if the DOM/JS is broken |
1808 | - // in the host browser. |
1809 | - Assert.isUndefined(this.widget.get("choice")); |
1810 | - } |
1811 | - else { |
1812 | - // The host browser's DOM/JS is sane. |
1813 | - ArrayAssert.itemsAreEqual( |
1814 | - ["b"], this.widget.get("choice")); |
1815 | - } |
1816 | - }, |
1817 | - |
1818 | - testSetChoiceWithCheckBox: function() { |
1819 | - this.widget |
1820 | - .set("type", "checkbox") |
1821 | - .set("choices", ["a", "b"]) |
1822 | - .set("choice", "a"); |
1823 | - ArrayAssert.itemsAreEqual( |
1824 | - ["a"], this.widget.get("choice")); |
1825 | - this.widget.set("choice", ["a"]); |
1826 | - ArrayAssert.itemsAreEqual( |
1827 | - ["a"], this.widget.get("choice")); |
1828 | - this.widget.set("choice", ["a", "b"]); |
1829 | - ArrayAssert.itemsAreEqual( |
1830 | - ["a", "b"], this.widget.get("choice")); |
1831 | - this.widget.set("choice", ["b", "c"]); |
1832 | - ArrayAssert.itemsAreEqual( |
1833 | - ["b"], this.widget.get("choice")); |
1834 | - }, |
1835 | - |
1836 | - testSetChoiceWithRadio: function() { |
1837 | - this.widget |
1838 | - .set("type", "radio") |
1839 | - .set("choices", ["a", "b"]) |
1840 | - .set("choice", "a"); |
1841 | - ArrayAssert.itemsAreEqual( |
1842 | - "a", this.widget.get("choice")); |
1843 | - this.widget.set("choice", ["a"]); |
1844 | - ArrayAssert.itemsAreEqual( |
1845 | - "a", this.widget.get("choice")); |
1846 | - this.widget.set("choice", "b"); |
1847 | - ArrayAssert.itemsAreEqual( |
1848 | - "b", this.widget.get("choice")); |
1849 | - } |
1850 | - |
1851 | - }; |
1852 | - |
1853 | - testChoiceListWidget = Y.merge( |
1854 | - testFormRowWidget, testChoiceListWidget); |
1855 | - suite.add(new Y.Test.Case(testChoiceListWidget)); |
1856 | - |
1857 | var testParentSeriesListWidget = { |
1858 | name: 'TestParentSeriesListWidget', |
1859 | |
1860 | @@ -367,6 +71,7 @@ |
1861 | }, |
1862 | |
1863 | testAddParentAddsLine: function() { |
1864 | + var parent; |
1865 | parent = {value: "4", title: "Hoary", api_uri: "ubuntu/hoary"}; |
1866 | Assert.areEqual( |
1867 | 0, |
1868 | @@ -382,6 +87,7 @@ |
1869 | }, |
1870 | |
1871 | testAddDuplicateParent: function() { |
1872 | + var parent; |
1873 | parent = {value: "4", title: "Hoary", api_uri: "ubuntu/hoary"}; |
1874 | Assert.isTrue( |
1875 | this.widget.add_parent(parent), |
1876 | @@ -396,6 +102,7 @@ |
1877 | }, |
1878 | |
1879 | testParentOrdering: function() { |
1880 | + var parent; |
1881 | parent = {value: "4", title: "Hoary", api_uri: "ubuntu/hoary"}; |
1882 | this.widget.add_parent(parent); |
1883 | parent = {value: "3", title: "Warty", api_uri: "ubuntu/warty"}; |
1884 | @@ -418,6 +125,7 @@ |
1885 | }, |
1886 | |
1887 | testRemoveParent: function() { |
1888 | + var parent; |
1889 | parent = {value: "4", title: "Hoary", api_uri: "ubuntu/hoary"}; |
1890 | this.widget.add_parent(parent); |
1891 | parent = {value: "3", title: "Warty", api_uri: "ubuntu/warty"}; |
1892 | @@ -460,7 +168,7 @@ |
1893 | }; |
1894 | |
1895 | testParentSeriesListWidget = Y.merge( |
1896 | - testFormRowWidget, testParentSeriesListWidget); |
1897 | + formwidgets.test.testFormRowWidget, testParentSeriesListWidget); |
1898 | suite.add(new Y.Test.Case(testParentSeriesListWidget)); |
1899 | |
1900 | var testArchitecturesChoiceListWidget = { |
1901 | @@ -561,209 +269,10 @@ |
1902 | }; |
1903 | |
1904 | testArchitecturesChoiceListWidget = Y.merge( |
1905 | - testChoiceListWidget, testArchitecturesChoiceListWidget); |
1906 | + formwidgets.test.testChoiceListWidget, |
1907 | + testArchitecturesChoiceListWidget); |
1908 | suite.add(new Y.Test.Case(testArchitecturesChoiceListWidget)); |
1909 | |
1910 | - var testSelectWidget = { |
1911 | - name: 'TestSelectWidget', |
1912 | - |
1913 | - choices: [ |
1914 | - {value: "a", text: "A", data: 123}, |
1915 | - {value: "b", text: "B", data: 456}, |
1916 | - {value: "c", text: "C", data: 789} |
1917 | - ], |
1918 | - |
1919 | - setUp: function() { |
1920 | - this.container = Y.Node.create("<div />"); |
1921 | - this.widget = new widgets.SelectWidget(); |
1922 | - }, |
1923 | - |
1924 | - tearDown: function() { |
1925 | - this.container.remove(true); |
1926 | - }, |
1927 | - |
1928 | - testNameChange: function() { |
1929 | - this.widget |
1930 | - .set("name", "foo") |
1931 | - .set("choices", this.choices); |
1932 | - var select = this.widget.fieldNode.one("select"); |
1933 | - Assert.areEqual("foo", select.get("name")); |
1934 | - this.widget |
1935 | - .set("name", "bar"); |
1936 | - Assert.areEqual("bar", select.get("name")); |
1937 | - }, |
1938 | - |
1939 | - testChoices: function() { |
1940 | - this.widget.set("choices", this.choices); |
1941 | - var choices_observed = this.widget.get("choices"); |
1942 | - /* We have to compare bit by bit ourselves because |
1943 | - Javascript is a language born in hell. */ |
1944 | - ArrayAssert.itemsAreEqual( |
1945 | - attrselect("value")(this.choices), |
1946 | - attrselect("value")(choices_observed)); |
1947 | - ArrayAssert.itemsAreEqual( |
1948 | - attrselect("text")(this.choices), |
1949 | - attrselect("text")(choices_observed)); |
1950 | - ArrayAssert.itemsAreEqual( |
1951 | - attrselect("data")(this.choices), |
1952 | - attrselect("data")(choices_observed)); |
1953 | - }, |
1954 | - |
1955 | - testRenderChoices: function() { |
1956 | - this.widget.set("choices", this.choices); |
1957 | - this.widget.render(this.container); |
1958 | - ArrayAssert.itemsAreEqual( |
1959 | - ["a", "b", "c"], |
1960 | - this.container.all("select > option").get("value")); |
1961 | - ArrayAssert.itemsAreEqual( |
1962 | - ["A", "B", "C"], |
1963 | - this.container.all("select > option").get("text")); |
1964 | - }, |
1965 | - |
1966 | - testRenderEmptyChoices: function() { |
1967 | - this.widget.fieldNode.append("something"); |
1968 | - this.widget.set("choices", []); |
1969 | - this.widget.render(this.container); |
1970 | - Assert.isNull(this.container.one("select")); |
1971 | - Assert.isFalse(this.widget.fieldNode.hasChildNodes()); |
1972 | - }, |
1973 | - |
1974 | - testRenderChoicesChange: function() { |
1975 | - var choices1 = [ |
1976 | - {value: "a", text: "A", data: 123} |
1977 | - ]; |
1978 | - this.widget.set("choices", choices1); |
1979 | - this.widget.render(this.container); |
1980 | - var choices2 = [ |
1981 | - {value: "b", text: "B", data: 456}, |
1982 | - {value: "c", text: "C", data: 789} |
1983 | - ]; |
1984 | - this.widget.set("choices", choices2); |
1985 | - ArrayAssert.itemsAreEqual( |
1986 | - ["b", "c"], |
1987 | - this.container.all("select > option").get("value")); |
1988 | - ArrayAssert.itemsAreEqual( |
1989 | - ["B", "C"], |
1990 | - this.container.all("select > option").get("text")); |
1991 | - }, |
1992 | - |
1993 | - testChoice: function() { |
1994 | - this.widget |
1995 | - .set("choices", this.choices) |
1996 | - .set("multiple", true); |
1997 | - /* It would be better to deselect all options by default, |
1998 | - but this appears impossible; the browser seems to |
1999 | - select the first option when rendering. */ |
2000 | - this.widget.fieldNode.all("option").set("selected", false); |
2001 | - ArrayAssert.itemsAreEqual( |
2002 | - [], this.widget.get("choice")); |
2003 | - this.widget.fieldNode.one("option[value=a]") |
2004 | - .set("selected", true); |
2005 | - ArrayAssert.itemsAreEqual( |
2006 | - ["a"], this.widget.get("choice")); |
2007 | - this.widget.fieldNode.one("option[value=c]") |
2008 | - .set("selected", true); |
2009 | - ArrayAssert.itemsAreEqual( |
2010 | - ["a", "c"], this.widget.get("choice")); |
2011 | - }, |
2012 | - |
2013 | - testSetChoice: function() { |
2014 | - this.widget |
2015 | - .set("multiple", true) |
2016 | - .set("choices", this.choices) |
2017 | - .set("choice", "a"); |
2018 | - ArrayAssert.itemsAreEqual( |
2019 | - ["a"], this.widget.get("choice")); |
2020 | - this.widget.set("choice", ["a"]); |
2021 | - ArrayAssert.itemsAreEqual( |
2022 | - ["a"], this.widget.get("choice")); |
2023 | - this.widget.set("choice", ["a", "b"]); |
2024 | - ArrayAssert.itemsAreEqual( |
2025 | - ["a", "b"], this.widget.get("choice")); |
2026 | - this.widget.set("choice", ["b", "z"]); |
2027 | - ArrayAssert.itemsAreEqual( |
2028 | - ["b"], this.widget.get("choice")); |
2029 | - }, |
2030 | - |
2031 | - testSize: function() { |
2032 | - Assert.areEqual(1, this.widget.get("size")); |
2033 | - }, |
2034 | - |
2035 | - testRenderSize: function() { |
2036 | - this.widget |
2037 | - .set("choices", this.choices) |
2038 | - .set("size", 7) |
2039 | - .render(this.container); |
2040 | - Assert.areEqual( |
2041 | - 7, this.widget.fieldNode.one("select").get("size")); |
2042 | - }, |
2043 | - |
2044 | - testRenderSizeChange: function() { |
2045 | - this.widget |
2046 | - .set("choices", this.choices) |
2047 | - .set("size", 3) |
2048 | - .render(this.container) |
2049 | - .set("size", 5); |
2050 | - Assert.areEqual( |
2051 | - 5, this.widget.fieldNode.one("select").get("size")); |
2052 | - }, |
2053 | - |
2054 | - testAutoSize: function() { |
2055 | - this.widget.set("choices", this.choices); |
2056 | - /* Without argument, autoSize() sets the size to the same |
2057 | - as the number of choices. */ |
2058 | - this.widget.autoSize(); |
2059 | - Assert.areEqual(3, this.widget.get("size")); |
2060 | - }, |
2061 | - |
2062 | - testAutoSizeMoreChoicesThanMaxiumum: function() { |
2063 | - this.widget.set("choices", this.choices); |
2064 | - /* autoSize() sets the size to the same as the number of |
2065 | - choices unless there are more than the specified |
2066 | - maximum. */ |
2067 | - this.widget.autoSize(2); |
2068 | - Assert.areEqual(2, this.widget.get("size")); |
2069 | - }, |
2070 | - |
2071 | - testAutoSizeFewerChoicesThanMaxiumum: function() { |
2072 | - this.widget.set("choices", this.choices); |
2073 | - /* autoSize() sets the size to the same as the number of |
2074 | - choices. */ |
2075 | - this.widget.autoSize(5); |
2076 | - Assert.areEqual(3, this.widget.get("size")); |
2077 | - }, |
2078 | - |
2079 | - testMultiple: function() { |
2080 | - Assert.areEqual(false, this.widget.get("multiple")); |
2081 | - }, |
2082 | - |
2083 | - testRenderMultiple: function() { |
2084 | - this.widget |
2085 | - .set("choices", this.choices) |
2086 | - .set("multiple", true) |
2087 | - .render(this.container); |
2088 | - Assert.isTrue( |
2089 | - this.widget.fieldNode.one("select") |
2090 | - .hasAttribute("multiple")); |
2091 | - }, |
2092 | - |
2093 | - testRenderMultipleChange: function() { |
2094 | - this.widget |
2095 | - .set("choices", this.choices) |
2096 | - .set("multiple", true) |
2097 | - .render(this.container) |
2098 | - .set("multiple", false); |
2099 | - Assert.isFalse( |
2100 | - this.widget.fieldNode.one("select") |
2101 | - .hasAttribute("multiple")); |
2102 | - } |
2103 | - |
2104 | - }; |
2105 | - |
2106 | - testSelectWidget = Y.merge( |
2107 | - testFormRowWidget, testSelectWidget); |
2108 | - suite.add(new Y.Test.Case(testSelectWidget)); |
2109 | - |
2110 | var testPackagesetPickerWidget = { |
2111 | name: 'TestPackagesetPickerWidget', |
2112 | |
2113 | @@ -968,79 +477,14 @@ |
2114 | }; |
2115 | |
2116 | testPackagesetPickerWidget = Y.merge( |
2117 | - testSelectWidget, testPackagesetPickerWidget); |
2118 | + formwidgets.test.testSelectWidget, testPackagesetPickerWidget); |
2119 | suite.add(new Y.Test.Case(testPackagesetPickerWidget)); |
2120 | |
2121 | - var testFormActionsWidget = { |
2122 | - name: 'TestFormActionsWidget', |
2123 | - |
2124 | - makeActionsDiv: function() { |
2125 | - var submit = Y.Node.create("<input />") |
2126 | - .set("type", "submit") |
2127 | - .set("value", "Initialize Series"); |
2128 | - var cancel = Y.Node.create("<a>Cancel</a>"); |
2129 | - var div = Y.Node.create("<div />") |
2130 | - .addClass("actions") |
2131 | - .append(submit) |
2132 | - .append(cancel); |
2133 | - return div; |
2134 | - }, |
2135 | - |
2136 | - setUp: function() { |
2137 | - this.actions = this.makeActionsDiv(); |
2138 | - this.widget = new widgets.FormActionsWidget( |
2139 | - {srcNode: this.actions}); |
2140 | - }, |
2141 | - |
2142 | - tearDown: function() { |
2143 | - this.actions.remove(true); |
2144 | - }, |
2145 | - |
2146 | - testInitializer: function() { |
2147 | - Assert.isTrue( |
2148 | - this.actions.one("input").compareTo( |
2149 | - this.widget.submitButtonNode)); |
2150 | - }, |
2151 | - |
2152 | - testSpinner: function() { |
2153 | - Assert.isTrue( |
2154 | - this.actions.contains(this.widget.submitButtonNode)); |
2155 | - Assert.isFalse( |
2156 | - this.actions.contains(this.widget.spinnerNode)); |
2157 | - this.widget.showSpinner(); |
2158 | - Assert.isFalse( |
2159 | - this.actions.contains(this.widget.submitButtonNode)); |
2160 | - Assert.isTrue( |
2161 | - this.actions.contains(this.widget.spinnerNode)); |
2162 | - this.widget.hideSpinner(); |
2163 | - Assert.isTrue( |
2164 | - this.actions.contains(this.widget.submitButtonNode)); |
2165 | - Assert.isFalse( |
2166 | - this.actions.contains(this.widget.spinnerNode)); |
2167 | - }, |
2168 | - |
2169 | - testShowError: function() { |
2170 | - this.widget.showError("The Man From U.N.C.L.E."); |
2171 | - Assert.areEqual( |
2172 | - "The Man From U.N.C.L.E.", |
2173 | - this.actions.one("p.error.message").get("text")); |
2174 | - }, |
2175 | - |
2176 | - testHideErrors: function() { |
2177 | - this.widget.showError("The Man From U.N.C.L.E."); |
2178 | - this.widget.showError("The Woman From A.U.N.T.I.E."); |
2179 | - this.widget.hideErrors(); |
2180 | - Assert.isNull(this.actions.one("p.error.message")); |
2181 | - } |
2182 | - |
2183 | - }; |
2184 | - |
2185 | - suite.add(new Y.Test.Case(testFormActionsWidget)); |
2186 | |
2187 | // Exports. |
2188 | - namespace.testFormActionsWidget = testFormActionsWidget; |
2189 | namespace.suite = suite; |
2190 | |
2191 | }, "0.1", {"requires": [ |
2192 | 'test', 'console', 'node-event-simulate', |
2193 | - 'lp.registry.distroseries.widgets']}); |
2194 | + 'lp.registry.distroseries.widgets', 'lp.app.formwidgets', |
2195 | + 'lp.app.formwidgets.test']}); |
2196 | |
2197 | === renamed file 'lib/lp/registry/javascript/distroseries.widgets.js' => 'lib/lp/registry/javascript/distroseries/widgets.js' |
2198 | --- lib/lp/registry/javascript/distroseries.widgets.js 2011-07-18 11:56:35 +0000 |
2199 | +++ lib/lp/registry/javascript/distroseries/widgets.js 2011-07-18 11:56:36 +0000 |
2200 | @@ -2,10 +2,10 @@ |
2201 | * Copyright 2011 Canonical Ltd. This software is licensed under the |
2202 | * GNU Affero General Public License version 3 (see the file LICENSE). |
2203 | * |
2204 | - * DistroSeries related stuff. |
2205 | + * DistroSeries Widgets. |
2206 | * |
2207 | - * @module registry |
2208 | - * @submodule distroseries |
2209 | + * @module lp.registry.distroseries |
2210 | + * @submodule widgets |
2211 | */ |
2212 | |
2213 | YUI.add('lp.registry.distroseries.widgets', function(Y) { |
2214 | @@ -14,154 +14,8 @@ |
2215 | |
2216 | var namespace = Y.namespace('lp.registry.distroseries.widgets'); |
2217 | |
2218 | - |
2219 | -/** |
2220 | - * A form row matching that which LaunchpadForm presents, containing a |
2221 | - * field (defined in a subclass), and an optional label and |
2222 | - * description. |
2223 | - * |
2224 | - * @class FormRowWidget |
2225 | - */ |
2226 | -var FormRowWidget; |
2227 | - |
2228 | -FormRowWidget = function() { |
2229 | - FormRowWidget.superclass.constructor.apply(this, arguments); |
2230 | -}; |
2231 | - |
2232 | -Y.mix(FormRowWidget, { |
2233 | - |
2234 | - NAME: 'formRowWidget', |
2235 | - |
2236 | - ATTRS: { |
2237 | - |
2238 | - /** |
2239 | - * The field name. |
2240 | - * |
2241 | - * @property name |
2242 | - */ |
2243 | - name: { |
2244 | - setter: function(value, name) { |
2245 | - this.fieldNode.all("input, select").set("name", value); |
2246 | - } |
2247 | - }, |
2248 | - |
2249 | - /** |
2250 | - * The top label for the field. |
2251 | - * |
2252 | - * @property label |
2253 | - */ |
2254 | - label: { |
2255 | - getter: function() { |
2256 | - return this.labelNode.get("text"); |
2257 | - }, |
2258 | - setter: function(value, name) { |
2259 | - this.labelNode.set("text", value); |
2260 | - } |
2261 | - }, |
2262 | - |
2263 | - /** |
2264 | - * A dictionary {link:link, text:text} to populate |
2265 | - * the pop-up help for the field. |
2266 | - * |
2267 | - * @property help |
2268 | - */ |
2269 | - help: { |
2270 | - getter: function() { |
2271 | - return {link:this.helpNode.one('a') |
2272 | - .get("href"), |
2273 | - text:this.helpNode |
2274 | - .one('.invisible-link') |
2275 | - .get("text")}; |
2276 | - }, |
2277 | - setter: function(value, name) { |
2278 | - if ((value.link !== undefined) && |
2279 | - (value.text !== undefined)) { |
2280 | - this.helpNode.one('a').set("href", value.link); |
2281 | - this.helpNode.one('.invisible-link') |
2282 | - .set("text", value.text); |
2283 | - this.helpNode.removeClass('unseen'); |
2284 | - } |
2285 | - else { |
2286 | - this.helpNode.addClass('unseen'); |
2287 | - } |
2288 | - } |
2289 | - }, |
2290 | - |
2291 | - /** |
2292 | - * A description shown near the field. |
2293 | - * |
2294 | - * @label description |
2295 | - */ |
2296 | - description: { |
2297 | - getter: function() { |
2298 | - return this.descriptionNode.get("text"); |
2299 | - }, |
2300 | - setter: function(value, name) { |
2301 | - this.descriptionNode.set("text", value); |
2302 | - } |
2303 | - } |
2304 | - } |
2305 | - |
2306 | -}); |
2307 | - |
2308 | -Y.extend(FormRowWidget, Y.Widget, { |
2309 | - |
2310 | - BOUNDING_TEMPLATE: "<tr></tr>", |
2311 | - |
2312 | - CONTENT_TEMPLATE: '<td colspan="2"></td>', |
2313 | - |
2314 | - initializer: function(config) { |
2315 | - this.labelNode = Y.Node.create("<label />"); |
2316 | - this.helpNode = Y.Node.create(('<span class="helper unseen">'+ |
2317 | - ' <a href=""' + |
2318 | - 'target="help" class="sprite maybe"> ' + |
2319 | - '<span class="invisible-link"></span></a></span>')); |
2320 | - this.fieldNode = Y.Node.create("<div></div>"); |
2321 | - this.descriptionNode = Y.Node.create('<p class="formHelp" />'); |
2322 | - this.spinnerNode = Y.Node.create( |
2323 | - '<img src="/@@/spinner" alt="Loading..." />'); |
2324 | - }, |
2325 | - |
2326 | - renderUI: function() { |
2327 | - this.get("contentBox") |
2328 | - .append(this.labelNode) |
2329 | - .append(this.helpNode) |
2330 | - .append(this.fieldNode) |
2331 | - .append(this.descriptionNode); |
2332 | - }, |
2333 | - |
2334 | - /** |
2335 | - * Show the spinner. |
2336 | - * |
2337 | - * @method showSpinner |
2338 | - */ |
2339 | - showSpinner: function() { |
2340 | - this.fieldNode.empty().append(this.spinnerNode); |
2341 | - }, |
2342 | - |
2343 | - /** |
2344 | - * Hide the spinner. |
2345 | - * |
2346 | - * @method hideSpinner |
2347 | - */ |
2348 | - hideSpinner: function() { |
2349 | - this.spinnerNode.remove(); |
2350 | - }, |
2351 | - |
2352 | - /** |
2353 | - * Display an error. |
2354 | - * |
2355 | - * @method showError |
2356 | - */ |
2357 | - showError: function(error) { |
2358 | - var message = Y.Node.create('<p />').set("text", error); |
2359 | - this.fieldNode.empty().append(message); |
2360 | - Y.lazr.anim.red_flash({node: message}).run(); |
2361 | - } |
2362 | - |
2363 | -}); |
2364 | - |
2365 | -namespace.FormRowWidget = FormRowWidget; |
2366 | +var formwidgets = Y.lp.app.formwidgets; |
2367 | + |
2368 | |
2369 | /** |
2370 | * A table to display, order, delete the selected parent series. Each parent |
2371 | @@ -249,7 +103,7 @@ |
2372 | } |
2373 | }); |
2374 | |
2375 | -Y.extend(ParentSeriesListWidget, FormRowWidget, { |
2376 | +Y.extend(ParentSeriesListWidget, formwidgets.FormRowWidget, { |
2377 | |
2378 | initializer: function() { |
2379 | ParentSeriesListWidget.superclass.initializer(); |
2380 | @@ -465,203 +319,6 @@ |
2381 | |
2382 | |
2383 | /** |
2384 | - * A form row matching that which LaunchpadForm presents, containing a |
2385 | - * list of checkboxes, and an optional label and description. |
2386 | - * |
2387 | - * @class ChoiceListWidget |
2388 | - */ |
2389 | -var ChoiceListWidget; |
2390 | - |
2391 | -ChoiceListWidget = function() { |
2392 | - ChoiceListWidget.superclass.constructor.apply(this, arguments); |
2393 | -}; |
2394 | - |
2395 | -Y.mix(ChoiceListWidget, { |
2396 | - |
2397 | - NAME: 'choiceListWidget', |
2398 | - |
2399 | - ATTRS: { |
2400 | - |
2401 | - /** |
2402 | - * An array of strings from which to choose. |
2403 | - * |
2404 | - * @property choices |
2405 | - */ |
2406 | - choices: { |
2407 | - getter: function() { |
2408 | - return this.fieldNode.all("li > input").get("value"); |
2409 | - }, |
2410 | - setter: function(value, name) { |
2411 | - var choices = Y.Array.unique(value).sort(); |
2412 | - var list = Y.Node.create("<ul />"); |
2413 | - var self = this; |
2414 | - choices.forEach( |
2415 | - function(choice) { |
2416 | - var item = self._createChoice(choice); |
2417 | - list.append(item); |
2418 | - } |
2419 | - ); |
2420 | - this.fieldNode.empty().append(list); |
2421 | - } |
2422 | - }, |
2423 | - |
2424 | - /** |
2425 | - * The current selection. |
2426 | - * |
2427 | - * @property choice |
2428 | - */ |
2429 | - choice: { |
2430 | - setter: function(value, name) { |
2431 | - if (!Y.Lang.isArray(value)) { |
2432 | - value = [value]; |
2433 | - } |
2434 | - this.fieldNode.all("li > input").each( |
2435 | - function(node) { |
2436 | - node.set( |
2437 | - "checked", |
2438 | - value.indexOf(node.get("value")) >= 0); |
2439 | - } |
2440 | - ); |
2441 | - }, |
2442 | - getter: function() { |
2443 | - var choice = []; |
2444 | - this.fieldNode.all("li > input").each( |
2445 | - function(node) { |
2446 | - if (node.get("checked")) { |
2447 | - choice.push(node.get("value")); |
2448 | - } |
2449 | - } |
2450 | - ); |
2451 | - if (this.get("type") === "radio") { |
2452 | - if (choice.length === 0) { |
2453 | - choice = null; |
2454 | - } |
2455 | - else if (choice.length === 1) { |
2456 | - choice = choice[0]; |
2457 | - } |
2458 | - else { |
2459 | - choice = undefined; |
2460 | - } |
2461 | - } |
2462 | - return choice; |
2463 | - } |
2464 | - }, |
2465 | - |
2466 | - /** |
2467 | - * The input type to display. Choose from "checkbox" or "radio". |
2468 | - * |
2469 | - * @property type |
2470 | - */ |
2471 | - type: { |
2472 | - value: "checkbox", |
2473 | - setter: function(value, name) { |
2474 | - this.fieldNode.all("li > input").set("type", value); |
2475 | - } |
2476 | - } |
2477 | - |
2478 | - } |
2479 | - |
2480 | -}); |
2481 | - |
2482 | -Y.extend(ChoiceListWidget, FormRowWidget, { |
2483 | - |
2484 | - /** |
2485 | - * Helper method to create an entry for the select widget. |
2486 | - * |
2487 | - * @method _createChoice |
2488 | - */ |
2489 | - _createChoice: function(choice) { |
2490 | - var field_name = this.get("name"); |
2491 | - var field_type = this.get("type"); |
2492 | - var item = Y.Node.create( |
2493 | - "<li><input /> <label /></li>"); |
2494 | - item.one("input") |
2495 | - .set("type", field_type) |
2496 | - .set("name", field_name) |
2497 | - .set("value", choice); |
2498 | - item.one("label") |
2499 | - .setAttribute( |
2500 | - "for", item.one("input").generateID()) |
2501 | - .setStyle("font-weight", "normal") |
2502 | - .set("text", choice); |
2503 | - return item; |
2504 | - }, |
2505 | - |
2506 | - /** |
2507 | - * Remove a list of choices from the possible widget's choices. |
2508 | - * |
2509 | - * @method remove_choices |
2510 | - */ |
2511 | - remove_choices: function(choices) { |
2512 | - choices.forEach( |
2513 | - function(choice) { |
2514 | - this.fieldNode.all("select > option").each( |
2515 | - function(option) { options.push(option); }); |
2516 | - this.fieldNode.all( |
2517 | - "li input[value=" + choice + "]").each( |
2518 | - function(li_input) { |
2519 | - li_input.get('parentNode').remove(); |
2520 | - } |
2521 | - ); |
2522 | - }, |
2523 | - this |
2524 | - ); |
2525 | - Y.lazr.anim.green_flash({node: this.fieldNode}).run(); |
2526 | - }, |
2527 | - |
2528 | - _sorted_position: function(choice) { |
2529 | - var options = []; |
2530 | - this.fieldNode.all("input").each( |
2531 | - function(node) { |
2532 | - options.push(node.get('value')); |
2533 | - } |
2534 | - ); |
2535 | - options.push(choice); |
2536 | - return options.sort().indexOf(choice); |
2537 | - }, |
2538 | - |
2539 | - /** |
2540 | - * Add new choices (if they are not already present). |
2541 | - * |
2542 | - * @method add_choices |
2543 | - */ |
2544 | - add_choices: function(new_choices) { |
2545 | - new_choices.forEach( |
2546 | - function(choice) { |
2547 | - if (this.fieldNode.all( |
2548 | - "li > input[value=" + choice + "]").isEmpty()) { |
2549 | - var list = this.fieldNode.one('ul'); |
2550 | - if (list === null) { |
2551 | - list = Y.Node.create("<ul />"); |
2552 | - this.fieldNode.empty().append(list); |
2553 | - } |
2554 | - var option = this._createChoice(choice); |
2555 | - var options = list.all('input'); |
2556 | - if (options.isEmpty()) { |
2557 | - list.append(option); |
2558 | - } |
2559 | - else { |
2560 | - var pos = this._sorted_position(choice); |
2561 | - if (pos === 0) { |
2562 | - list.prepend(option); |
2563 | - } |
2564 | - else { |
2565 | - list.insertBefore(option, options.item(pos)); |
2566 | - } |
2567 | - } |
2568 | - } |
2569 | - }, this |
2570 | - ); |
2571 | - Y.lazr.anim.green_flash({node: this.fieldNode}).run(); |
2572 | - } |
2573 | - |
2574 | -}); |
2575 | - |
2576 | - |
2577 | -namespace.ChoiceListWidget = ChoiceListWidget; |
2578 | - |
2579 | - |
2580 | -/** |
2581 | * A special form of ChoiceListWidget for choosing architecture tags. |
2582 | * |
2583 | * @class ArchitecturesChoiceListWidget |
2584 | @@ -682,7 +339,7 @@ |
2585 | |
2586 | }); |
2587 | |
2588 | -Y.extend(ArchitecturesChoiceListWidget, ChoiceListWidget, { |
2589 | +Y.extend(ArchitecturesChoiceListWidget, formwidgets.ChoiceListWidget, { |
2590 | |
2591 | initializer: function(config) { |
2592 | this.client = new Y.lp.client.Launchpad(); |
2593 | @@ -787,175 +444,6 @@ |
2594 | |
2595 | |
2596 | /** |
2597 | - * A special form of FormRowWidget, containing a select control. |
2598 | - * |
2599 | - * @class SelectWidget |
2600 | - */ |
2601 | -var SelectWidget; |
2602 | - |
2603 | -SelectWidget = function() { |
2604 | - SelectWidget.superclass.constructor.apply(this, arguments); |
2605 | -}; |
2606 | - |
2607 | -Y.mix(SelectWidget, { |
2608 | - |
2609 | - NAME: 'selectWidget', |
2610 | - |
2611 | - ATTRS: { |
2612 | - |
2613 | - /** |
2614 | - * An array of objects from which to choose. Each object |
2615 | - * should contain a value for "value", "text" and "data". |
2616 | - * |
2617 | - * @property choices |
2618 | - */ |
2619 | - choices: { |
2620 | - getter: function() { |
2621 | - /* I think this is a YUI3 wart; I can't see any way to |
2622 | - map() over a NodeList, so I must push the elements |
2623 | - one by one into an array first. */ |
2624 | - var options = Y.Array([]); |
2625 | - this.fieldNode.all("select > option").each( |
2626 | - function(option) { options.push(option); }); |
2627 | - return options.map( |
2628 | - function(option) { |
2629 | - return { |
2630 | - value: option.get("value"), |
2631 | - text: option.get("text"), |
2632 | - data: option.getData("data") |
2633 | - }; |
2634 | - } |
2635 | - ); |
2636 | - }, |
2637 | - setter: function(value, name) { |
2638 | - var select = Y.Node.create("<select />"); |
2639 | - select.set("name", this.get("name")) |
2640 | - .set("size", this.get("size")); |
2641 | - if (this.get("multiple")) { |
2642 | - select.set("multiple", "multiple"); |
2643 | - } |
2644 | - var choices = Y.Array(value); |
2645 | - choices.forEach( |
2646 | - function(choice) { |
2647 | - var option = Y.Node.create("<option />"); |
2648 | - option.set("value", choice.value) |
2649 | - .set("text", choice.text) |
2650 | - .setData("data", choice.data); |
2651 | - select.append(option); |
2652 | - } |
2653 | - ); |
2654 | - if (choices.length > 0) { |
2655 | - this.fieldNode.empty().append(select); |
2656 | - } |
2657 | - else { |
2658 | - this.fieldNode.empty(); |
2659 | - } |
2660 | - } |
2661 | - }, |
2662 | - |
2663 | - /** |
2664 | - * The current selection. |
2665 | - * |
2666 | - * @property choice |
2667 | - */ |
2668 | - choice: { |
2669 | - setter: function(value, name) { |
2670 | - if (!Y.Lang.isArray(value)) { |
2671 | - value = [value]; |
2672 | - } |
2673 | - this.fieldNode.all("select > option").each( |
2674 | - function(node) { |
2675 | - node.set( |
2676 | - "selected", |
2677 | - value.indexOf(node.get("value")) >= 0); |
2678 | - } |
2679 | - ); |
2680 | - }, |
2681 | - getter: function() { |
2682 | - var choice = []; |
2683 | - this.fieldNode.all("select > option").each( |
2684 | - function(node) { |
2685 | - if (node.get("selected")) { |
2686 | - choice.push(node.get("value")); |
2687 | - } |
2688 | - } |
2689 | - ); |
2690 | - return choice; |
2691 | - } |
2692 | - }, |
2693 | - |
2694 | - /** |
2695 | - * The number of rows to show in the select widget. |
2696 | - * |
2697 | - * @property size |
2698 | - */ |
2699 | - size: { |
2700 | - value: 1, |
2701 | - setter: function(value, name) { |
2702 | - this.fieldNode.all("select").set("size", value); |
2703 | - } |
2704 | - }, |
2705 | - |
2706 | - /** |
2707 | - * Whether multiple rows can be selected. |
2708 | - * |
2709 | - * @property multiple |
2710 | - */ |
2711 | - multiple: { |
2712 | - value: false, |
2713 | - setter: function(value, name) { |
2714 | - value = value ? true : false; |
2715 | - this.fieldNode.all("select").set("multiple", value); |
2716 | - return value; |
2717 | - } |
2718 | - } |
2719 | - |
2720 | - } |
2721 | - |
2722 | -}); |
2723 | - |
2724 | -Y.extend(SelectWidget, FormRowWidget, { |
2725 | - |
2726 | - _sorted_position: function(choice) { |
2727 | - var options = []; |
2728 | - this.fieldNode.all("option").each( |
2729 | - function(node) { |
2730 | - options.push(node.get('text')); |
2731 | - } |
2732 | - ); |
2733 | - options.push(choice); |
2734 | - return options.sort().indexOf(choice); |
2735 | - }, |
2736 | - |
2737 | - /** |
2738 | - * Choose a size for the select control based on the number of |
2739 | - * choices, up to an optional maximum size. |
2740 | - * |
2741 | - * @method autoSize |
2742 | - */ |
2743 | - autoSize: function(maxSize) { |
2744 | - var choiceCount = this.fieldNode.all("select > option").size(); |
2745 | - if (choiceCount === 0) { |
2746 | - this.set("size", 1); |
2747 | - } |
2748 | - else if (maxSize === undefined) { |
2749 | - this.set("size", choiceCount); |
2750 | - } |
2751 | - else if (choiceCount < maxSize) { |
2752 | - this.set("size", choiceCount); |
2753 | - } |
2754 | - else { |
2755 | - this.set("size", maxSize); |
2756 | - } |
2757 | - return this; |
2758 | - } |
2759 | - |
2760 | -}); |
2761 | - |
2762 | -namespace.SelectWidget = SelectWidget; |
2763 | - |
2764 | - |
2765 | -/** |
2766 | * A special form of SelectWidget for choosing packagesets. |
2767 | * |
2768 | * @class PackagesetPickerWidget |
2769 | @@ -1001,7 +489,7 @@ |
2770 | }); |
2771 | |
2772 | |
2773 | -Y.extend(PackagesetPickerWidget, SelectWidget, { |
2774 | +Y.extend(PackagesetPickerWidget, formwidgets.SelectWidget, { |
2775 | |
2776 | /** |
2777 | * Add a distroseries: add its packagesets to the packageset picker. |
2778 | @@ -1152,96 +640,7 @@ |
2779 | namespace.PackagesetPickerWidget = PackagesetPickerWidget; |
2780 | |
2781 | |
2782 | -/** |
2783 | - * A widget to encapsulate functionality around the form actions. |
2784 | - * |
2785 | - * @class FormActionsWidget |
2786 | - */ |
2787 | -var FormActionsWidget; |
2788 | - |
2789 | -FormActionsWidget = function() { |
2790 | - FormActionsWidget |
2791 | - .superclass.constructor.apply(this, arguments); |
2792 | -}; |
2793 | - |
2794 | -FormActionsWidget.ATTRS = { |
2795 | - duration: { |
2796 | - value: 1.0 |
2797 | - }, |
2798 | - |
2799 | - height: { |
2800 | - value: 0 |
2801 | - }, |
2802 | - |
2803 | - opacity: { |
2804 | - value: 0 |
2805 | - } |
2806 | -}; |
2807 | - |
2808 | - |
2809 | -Y.mix(FormActionsWidget, { |
2810 | - |
2811 | - NAME: 'formActionsWidget', |
2812 | - |
2813 | - HTML_PARSER: { |
2814 | - submitButtonNode: "input[type=submit]" |
2815 | - } |
2816 | - |
2817 | -}); |
2818 | - |
2819 | -Y.extend(FormActionsWidget, Y.Widget, { |
2820 | - |
2821 | - initializer: function(config) { |
2822 | - this.client = new Y.lp.client.Launchpad(); |
2823 | - this.error_handler = new Y.lp.client.ErrorHandler(); |
2824 | - this.error_handler.clearProgressUI = Y.bind(this.hideSpinner, this); |
2825 | - this.error_handler.showError = Y.bind(this.showError, this); |
2826 | - this.submitButtonNode = config.submitButtonNode; |
2827 | - this.spinnerNode = Y.Node.create( |
2828 | - '<img src="/@@/spinner" alt="Loading..." />'); |
2829 | - }, |
2830 | - |
2831 | - /** |
2832 | - * Show the spinner, and hide the submit button. |
2833 | - * |
2834 | - * @method showSpinner |
2835 | - */ |
2836 | - showSpinner: function() { |
2837 | - this.submitButtonNode.replace(this.spinnerNode); |
2838 | - }, |
2839 | - |
2840 | - /** |
2841 | - * Hide the spinner, and show the submit button again. |
2842 | - * |
2843 | - * @method hideSpinner |
2844 | - */ |
2845 | - hideSpinner: function() { |
2846 | - this.spinnerNode.replace(this.submitButtonNode); |
2847 | - }, |
2848 | - |
2849 | - /** |
2850 | - * Display an error. |
2851 | - * |
2852 | - * @method showError |
2853 | - */ |
2854 | - showError: function(error) { |
2855 | - Y.Node.create('<p class="error message" />') |
2856 | - .appendTo(this.get("contentBox")) |
2857 | - .set("text", error); |
2858 | - }, |
2859 | - |
2860 | - /** |
2861 | - * Remove all errors that have been previously displayed by showError. |
2862 | - * |
2863 | - * @method hideErrors |
2864 | - */ |
2865 | - hideErrors: function(error) { |
2866 | - this.get("contentBox").all("p.error.message").remove(); |
2867 | - } |
2868 | - |
2869 | -}); |
2870 | - |
2871 | -namespace.FormActionsWidget = FormActionsWidget; |
2872 | - |
2873 | -}, "0.1", {"requires": ["node", "dom", "io", "widget", "lp.client", |
2874 | - "lazr.anim", "array-extras", "transition"]}); |
2875 | +}, "0.1", {"requires": [ |
2876 | + "node", "dom", "io", "widget", "lp.client", |
2877 | + "lp.app.formwidgets", "lazr.anim", "array-extras", |
2878 | + "transition"]}); |