launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #04195
[Merge] lp:~danilo/launchpad/drop-collapsibles into lp:launchpad
Данило Шеган has proposed merging lp:~danilo/launchpad/drop-collapsibles into lp:launchpad with lp:~danilo/launchpad/replace-expanders-1 as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #807089 in Launchpad itself: "Replace collapsibles implementation with the new expander"
https://bugs.launchpad.net/launchpad/+bug/807089
For more details, see:
https://code.launchpad.net/~danilo/launchpad/drop-collapsibles/+merge/67224
= Bug 807089: replace collapsibles implementation =
Among many different collapsible/expandable/foldable animations, "activate_collapsibles" sticks through. It is called from base-layout-macros (so, for each and every page), and ideally wouldn't be (iow, we'd only set collapsibles up when really appropriate).
However, this branch only changes the implementation in lib/lp/app/javascript/lp.js to use the new generic Expander widget which animates much more nicely, thus removing all of toggle_collapsible() and most of activate_collapsibles() code, replacing it with two lines of code. Test files are another kills.
In all the places where collapsibles is used, the API is only slightly changed: 'collapsed' CSS class is not used anymore to make it appear collapsed initially (because that's the default). To not trigger the hiding from JS, no matter how fast, we instead introduce 'unseen' flag (as used by Expander itself) on appropriate content nodes.
In a few places, we also wrap <table> inside a <div> so it would animate nicely (<table> itself is not a simple display:block element, so 'height' setting doesn't work at all times). In those cases, I usually haven't indented the inner table because that would increase the diff size and I am already close to the limit. I'd be happy to do that after review, though (but please remind me :).
The most complex change is in the pillar-involvement-portlet.pt: we move the initial state from containing node to the content node, as expected by the Expander widget.
I haven't fixed the lp.js lint issues and I'd rather not (it's part of LPClient implementation, and fixes there should be a separate branch).
== Tests ==
Whatever is already there, mostly just QA that it all works. Tested in Epiphany (pure WebKit-based), Chromium and Firefox 5.
== Demo and Q/A ==
1. https://bugs.launchpad.dev/redfish/+filebug
Search for 'a' then play with "Extra options" expander: note how it works much better then the matching bugs expanders when clicked quickly in succession.
2. https://code.launchpad.dev/~name12/landscape/feature-x/+register-merge ("Extra options")
3. https://launchpad.dev/firefox
"Configuration options" in a portlet on the right-hand side.
https://launchpad.dev/evolution
Configure all and reload to make sure it starts hidden because everything is set-up.
4. https://launchpad.dev/firefox/+download ("Release information")
5. https://launchpad.dev/firefox/trunk/0.9.2 (Edit change log, then come back to this page)
6. I need help to construct sample data for sourcepackagerecipe-related-branches.pt change.
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/app/javascript/expander.js
lib/lp/app/javascript/lp.js
lib/lp/bugs/templates/bugtarget-macros-filebug.pt
lib/lp/code/templates/branch-register-merge.pt
lib/lp/code/templates/sourcepackagerecipe-related-branches.pt
lib/lp/registry/templates/pillar-involvement-portlet.pt
lib/lp/registry/templates/product-files.pt
lib/lp/registry/templates/productrelease-portlet-data.pt
./lib/lp/app/javascript/lp.js
52: Expected '!==' and instead saw '!='.
91: Expected '===' and instead saw '=='.
106: Expected '===' and instead saw '=='.
107: Expected '===' and instead saw '=='.
139: Move 'var' declarations to the top of the function.
139: Stopping. (57% scanned).
-1: JSLINT had a fatal error.
--
https://code.launchpad.net/~danilo/launchpad/drop-collapsibles/+merge/67224
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~danilo/launchpad/drop-collapsibles into lp:launchpad.
=== modified file 'lib/lp/app/javascript/expander.js'
--- lib/lp/app/javascript/expander.js 2011-07-07 16:52:34 +0000
+++ lib/lp/app/javascript/expander.js 2011-07-07 16:52:35 +0000
@@ -284,19 +284,21 @@
* by widget_select.
* @param content_select CSS selector for the content tag inside each tag
* matched by widget_select.
+ * @param linkify Whether to linkify the content in the icon_select node.
* @param loader Optional loader function for each expander that is set up.
* Must take an Expander as its argument, create a Node or NodeList with
* the output to be displayed, and feed the output to the expander's
* "receive" method.
*/
-function createByCSS(widget_select, icon_select, content_select, loader) {
+function createByCSS(widget_select, icon_select, content_select, linkify,
+ loader) {
var config = {
loader: loader
};
var expander_factory = function(widget) {
var expander = new Expander(
widget.one(icon_select), widget.one(content_select), config);
- expander.setUp();
+ expander.setUp(linkify);
};
Y.all(widget_select).each(expander_factory);
}
=== modified file 'lib/lp/app/javascript/lp.js'
--- lib/lp/app/javascript/lp.js 2011-06-27 15:25:02 +0000
+++ lib/lp/app/javascript/lp.js 2011-07-07 16:52:35 +0000
@@ -54,218 +54,20 @@
};
/**
- * Toggle a collapsible's state from open to closed or vice-versa.
- *
- * @method toggle_collapsible
- * @param {Node} collapsible the collapsible to toggle.
- */
- Y.lp.toggle_collapsible = function(collapsible) {
- // Find the collapse icon and wrapper div for this collapsible.
- var icon = collapsible.one('.collapseIcon');
-
- function get_wrapper_div(node) {
- var wrapper_div = node.one('.collapseWrapper');
-
- // If either the wrapper or the icon is null, raise an error.
- if (wrapper_div === null) {
- Y.error("Collapsible has no wrapper div.");
- }
- if (icon === null) {
- Y.error("Collapsible has no icon.");
- }
- return wrapper_div;
- }
- var wrapper_div = get_wrapper_div(collapsible);
-
- // Work out the target icon and animation based on the state of
- // the collapse wrapper. We ignore the current state of the icon
- // because the collapse wrapper is the canonical guide as to
- // whether the item is collapsed or expanded. This saves us from
- // situations where we end up using the wrong icon for a given
- // state.
- var target_icon;
- var target_anim;
- var expanding;
- if (wrapper_div.hasClass('lazr-closed')) {
- // The wrapper is collapsed; expand it and collapse all its
- // siblings if it's in an accordion.
- expanding = true;
- target_anim = Y.lazr.effects.slide_out(wrapper_div);
- target_icon = "/@@/treeExpanded";
- } else {
- // The wrapper is open; just collapse it.
- expanding = false;
- target_anim = Y.lazr.effects.slide_in(wrapper_div);
- target_icon = "/@@/treeCollapsed";
- }
-
- // Run the animation and set the icon src correctly.
- target_anim.run();
- icon.set('src', target_icon);
-
- // Work out if the collapsible is in an accordion and process
- // the siblings accordingly if the current collapsible is being
- // expanded.
- var parent_node = collapsible.get('parentNode');
- var in_accordion = parent_node.hasClass('accordion');
- if (in_accordion && expanding) {
- var sibling_target_icon = "/@@/treeCollapsed";
- Y.each(parent_node.all('.collapsible'), function(sibling) {
- // We only actually collapse the sibling if it's not our
- // current collapsible.
- if (sibling != collapsible) {
- var sibling_wrapper_div = get_wrapper_div(sibling);
- var sibling_icon = sibling.one('.collapseIcon');
- var sibling_target_anim = Y.lazr.effects.slide_in(
- sibling_wrapper_div);
- sibling_target_anim.run();
- sibling_icon.set('src', sibling_target_icon);
- }
- });
- }
- };
-
- /**
* Activate all collapsible sections of a page.
*
* @method activate_collapsibles
*/
Y.lp.activate_collapsibles = function() {
- // Grab the collapsibles.
- Y.all('.collapsible').each(function(collapsible) {
-
- // Try to grab the legend in the usual way.
- var legend = collapsible.one('legend');
- if (legend === null) {
- // If it's null, this might be a collapsible div, not
- // fieldset, so try to grab the div's "legend".
- legend = collapsible.one('.config-options');
- }
- if (legend === null ||
- legend.one('.collapseIcon') !== null) {
- // If there's no legend there's not much we can do,
- // so just exit this iteration. If there's a
- // collapseIcon in there we consider the collapsible
- // to already have been set up and therefore ignore
- // it this time around.
- return;
- }
-
- var icon = Y.Node.create(
- '<img src="/@@/treeExpanded" class="collapseIcon" />');
-
- // We use javascript:void(0) here (though it will cause
- // lint to complain) because it prevents clicking on the
- // anchor from altering the page URL, which can subtly
- // break things.
- var anchor = Y.Node.create(
- '<a href="javascript:void(0);"></a>');
- anchor.appendChild(icon);
-
- // Move the contents of the legend into the span. We use
- // the verbose version of <span /> to avoid silly
- // breakages in Firefox.
- var span = Y.Node.create('<span></span>');
- var legend_children = legend.get('children');
- var len;
-
- if (Y.Lang.isValue(legend_children)) {
- // XXX 2009-07-06 gmb Account for oddness from
- // Node.get('children'); (see YUI ticket 2528028 for
- // details).
- len = legend_children.size ?
- legend_children.size() : legend_children.length;
- } else {
- len = 0;
- }
-
- if (len > 0) {
- // If the legend has child elements, move them
- // across one by one.
- Y.each(legend_children, function(child_node) {
- if (child_node.get('tagName') == 'A') {
- // If this child is an anchor, add only its
- // contents to the span.
- new_node = Y.Node.create(
- child_node.get('innerHTML'));
- span.appendChild(new_node);
- legend.removeChild(child_node);
- } else {
- // Otherwise, add the node to the span as it
- // is.
- span.appendChild(child_node);
- }
- });
- } else {
- // Otherwise just move the innerHTML across as a
- // block. Once the span is appended to the anchor,
- // this will essentially turn the contents of the
- // legend into a link.
- span.set('innerHTML', legend.get('innerHTML'));
- legend.set('innerHTML', '');
- }
-
- // Replace the contents of the legend with the anchor.
- anchor.appendChild(span);
- legend.appendChild(anchor);
-
- // Put a wrapper around the fieldset contents for ease
- // of hiding.
- var wrapper_div = Y.Node.create(
- '<div class="collapseWrapper" />');
-
- // Loop over the children of the collapsible and move them
- // into the wrapper div. We remove the legend from the
- // collapsible at this point to make sure it gets left
- // outside the wrapper div; we'll add it again later.
- collapsible.removeChild(legend);
-
- // "Why do this as a while?" I hear you cry. Well, it's
- // because using Y.each() leads to interesting results
- // in FF3.5, Opera and Chrome, since by doing
- // appendChild() with each child node (and thus removing
- // them from the collapsible) means you're altering the
- // collection as you're looping over it, which is a Bad
- // Thing. This isn't as pretty but it actually works.
- var first_child = collapsible.one(':first-child');
- while (Y.Lang.isValue(first_child)) {
- wrapper_div.appendChild(first_child);
- first_child = collapsible.one(':first-child');
- }
-
- // Put the legend and the new wrapper div into the
- // collapsible in the right order.
- collapsible.appendChild(legend);
- collapsible.appendChild(wrapper_div);
-
- // If the collapsible is to be collapsed on pageload, do
- // so.
- if (collapsible.hasClass('collapsed')) {
- // Strip out the 'collapsed' class as it's no longer
- // needed.
- collapsible.removeClass('collapsed');
-
- // We use the slide_in effect to hide the
- // collapsible because it sets up all the properties
- // and classes for the element properly and saves us
- // from embarrasment later on.
- var slide_in = Y.lazr.effects.slide_in(wrapper_div);
- slide_in.run();
-
- icon.set('src', '/@@/treeCollapsed');
- }
-
- // Finally, add toggle_collapsible() as an onclick
- // handler to the anchor.
- anchor.on('click', function(e) {
- Y.lp.toggle_collapsible(collapsible);
- });
- });
+ // CSS selector 'legend + *' gets the next sibling element.
+ Y.lp.app.widgets.expander.createByCSS(
+ '.collapsible', 'legend', 'legend + *', true);
};
+
Y.lp.get_url_path = function(url) {
return Y.Node.create('<a>junk</a>').set('href', url).get('pathname');
};
-}, "0.1", {"requires":["cookie", "lazr.effects"]});
+}, "0.1", {"requires":["cookie", "lazr.effects", "lp.app.widgets.expander"]});
// Lint-safe scripting URL.
=== removed file 'lib/lp/app/javascript/tests/test_lp_collapsibles.html'
--- lib/lp/app/javascript/tests/test_lp_collapsibles.html 2010-11-23 14:18:07 +0000
+++ lib/lp/app/javascript/tests/test_lp_collapsibles.html 1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
- <head>
- <title>Launchpad Collapsibles</title>
-
- <!-- YUI 3.0 Setup -->
- <script type="text/javascript" src="../../../../canonical/launchpad/icing/yui/yui/yui.js"></script>
- <script type="text/javascript" src="../../../../canonical/launchpad/icing/lazr/build/lazr.js"></script>
- <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssreset/reset.css"/>
- <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssfonts/fonts.css"/>
- <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssbase/base.css"/>
- <link rel="stylesheet" href="../../../../canonical/launchpad/javascript/test.css" />
-
- <!-- The module under test -->
- <script type="text/javascript" src="../lp.js"></script>
-
- <!-- The test suite -->
- <script type="text/javascript" src="test_lp_collapsibles.js"></script>
-</head>
-<body class="yui3-skin-sam">
- <div id="container-of-stuff">
- </div>
-</body>
-</html>
=== removed file 'lib/lp/app/javascript/tests/test_lp_collapsibles.js'
--- lib/lp/app/javascript/tests/test_lp_collapsibles.js 2011-06-22 18:53:35 +0000
+++ lib/lp/app/javascript/tests/test_lp_collapsibles.js 1970-01-01 00:00:00 +0000
@@ -1,350 +0,0 @@
-/* Copyright (c) 2009, Canonical Ltd. All rights reserved. */
-
-YUI({
- base: '../../../../canonical/launchpad/icing/yui/',
- filter: 'raw',
- combine: false,
- fetchCSS: false
- }).use('test', 'console', 'lp', 'lazr.effects', function(Y) {
-
-var Assert = Y.Assert; // For easy access to isTrue(), etc.
-
-var suite = new Y.Test.Suite("Collapsibles Tests");
-suite.add(new Y.Test.Case({
- name: "activate_collapsibles",
-
- _should: {
- error: {
- test_toggle_collapsible_fails_on_wrapperless_collapsible:
- new Error('Collapsible has no wrapper div.'),
- test_toggle_collapsible_fails_on_iconless_collapsible:
- new Error('Collapsible has no icon.')
- }
- },
-
- setUp: function() {
- // Create some individual Nodes that we can work with in
- // tests.
- this.default_legend_node = Y.Node.create(
- "<legend>My expander, let me collapse it</legend>");
- this.default_fieldset_node = Y.Node.create(
- '<fieldset class="collapsible" />');
- this.default_fieldset_content_node = Y.Node.create(
- "<p>Here's some content for ya.</p>");
-
- // Build the fieldset that we want to make collapsible.
- this.default_fieldset_node.appendChild(
- this.default_legend_node.cloneNode(
- this.default_legend_node));
-
- this.default_fieldset_node.appendChild(
- this.default_fieldset_content_node.cloneNode(
- this.default_fieldset_content_node));
-
- // Reset the container to its default contents.
- this.container = Y.one('#container-of-stuff');
- this.container.set('innerHTML', '');
- this.container.appendChild(
- this.default_fieldset_node.cloneNode(
- this.default_fieldset_node));
-
- // Monkey patch effects duration to make effects instant.
- // This keeps wait times to a minimum.
- this.original_defaults = Y.lazr.effects.slide_effect_defaults;
- Y.lazr.effects.slide_effect_defaults.duration = 0;
- },
-
- tearDown: function() {
- Y.lazr.effects.slide_effect_defaults = this.original_defaults;
- },
-
- test_activate_collapsibles_creates_anchor: function() {
- // activate_collapsibles() creates an anchor to handle the
- // business of toggling the collapsible open and shut.
- Y.lp.activate_collapsibles();
-
- var anchor = this.container.one('a');
- Assert.isNotNull(
- anchor, "activate_collapsibles() should create an anchor");
-
- // The anchor is for decoration only, so its URL is a simple
- // placeholder.
- Assert.areEqual('javascript:void(0);', anchor.get('href'));
- },
-
- test_activate_collapsibles_adds_icon_to_anchor: function() {
- // activate_collapsibles() adds an icon to the anchor it
- // creates.
- Y.lp.activate_collapsibles();
-
- var anchor = this.container.one('a');
- var icon = anchor.one('img');
-
- Assert.isNotNull(
- icon,
- "activate_collapsibles() should add an icon to the anchor " +
- "it creates");
-
- // By default, the icon is the treeExpanded icon.
- Assert.areNotEqual(
- -1, icon.get('src').indexOf('/@@/treeExpanded'));
- Assert.isTrue(icon.hasClass('collapseIcon'));
- },
-
- test_activate_collapsibles_adds_span_to_anchor: function() {
- // activate_collapsibles() adds a span to the anchor it creates.
- Y.lp.activate_collapsibles();
-
- var anchor = this.container.one('a');
- var span = anchor.one('span');
-
- Assert.isNotNull(
- span,
- "activate_collapsibles() should add a span to the anchor");
-
- // The span's contents will be the same as the original
- // legend's contents.
- Assert.areEqual(
- this.default_legend_node.get('innerHTML'),
- span.get('innerHTML'));
- },
-
- test_activate_collapsibles_adds_wrapper: function() {
- // activate_collapsibles() wraps the fieldset contents
- // (other than the legend) in a div which can then be
- // collapsed.
- Y.lp.activate_collapsibles();
-
- var wrapper_div = this.container.get('.collapseWrapper');
- Assert.isNotNull(
- wrapper_div,
- "activate_collapsibles() should add a wrapper div");
-
- var collapsible = this.container.one('.collapsible');
- Assert.isNotNull(
- collapsible.one('.collapseWrapper'),
- "The collapseWrapper div should be within the collapsible.");
- },
-
- test_activate_collapsibles_collapses_collapsed: function() {
- // If a collapsible has the class 'collapsed',
- // activate_collapsibles() will pre-collapse it.
- var collapsible = this.container.one('.collapsible');
- collapsible.addClass('collapsed');
-
- Y.lp.activate_collapsibles();
-
- var icon = collapsible.one('img');
- var wrapper_div = collapsible.one('.collapseWrapper');
- this.wait(function() {
- Assert.isTrue(wrapper_div.hasClass('lazr-closed'));
- Assert.areNotEqual(
- -1, icon.get('src').indexOf('/@@/treeCollapsed'));
- }, 20);
- },
-
- test_activate_collapsibles_doesnt_collapse_uncollapsed: function() {
- // If a collapsible doesn't have the 'collapsed' class it
- // won't be pre-collapsed.
- Y.lp.activate_collapsibles();
-
- var collapsible = this.container.one('.collapsible');
- var icon = collapsible.one('img');
- var wrapper_div = collapsible.one('.collapseWrapper');
- this.wait(function() {
- Assert.isFalse(wrapper_div.hasClass('lazr-closed'));
- Assert.areNotEqual(
- -1, icon.get('src').indexOf('/@@/treeExpanded'));
- }, 20);
- },
-
- test_toggle_collapsible_opens_collapsed_collapsible: function() {
- // Calling toggle_collapsible() on a collapsed collapsible will
- // toggle its state to open.
- Y.lp.activate_collapsibles();
- var collapsible = this.container.one('.collapsible');
- var wrapper_div = collapsible.one('.collapseWrapper');
- wrapper_div.addClass('lazr-closed');
-
- Y.lp.toggle_collapsible(collapsible);
- this.wait(function() {
- // The collapsible's wrapper div will now be open.
- var icon = collapsible.one('img');
- Assert.isFalse(wrapper_div.hasClass('lazr-closed'));
- Assert.areNotEqual(
- -1, icon.get('src').indexOf('/@@/treeExpanded'));
- }, 20);
- },
-
- test_toggle_collapsible_closes_open_collapsible: function() {
- // Calling toggle_collapsible() on an open collapsible will
- // toggle its state to closed.
- var collapsible = this.container.one('.collapsible');
-
- Y.lp.activate_collapsibles();
- Y.lp.toggle_collapsible(collapsible);
-
- this.wait(function() {
- // The collapsible's wrapper div will now be closed.
- var icon = collapsible.one('img');
- var wrapper_div = collapsible.one('.collapseWrapper');
- Assert.isTrue(wrapper_div.hasClass('lazr-closed'));
- Assert.areNotEqual(
- -1, icon.get('src').indexOf('/@@/treeCollapsed'));
- }, 20);
-
- },
-
- test_toggle_collapsible_fails_on_wrapperless_collapsible: function() {
- // If the collapsible passed to toggle_collapsible() has no
- // wrapper div, toggle_collapsible() will raise an error.
- var invalid_collapsible = Y.Node.create(
- '<fieldset class="collapsible"> ' +
- ' <img src="#" class="collapseIcon" />' +
- ' <p>No contents!</p>' +
- '</fieldset>');
-
- Y.lp.toggle_collapsible(invalid_collapsible);
- },
-
- test_toggle_collapsible_fails_on_iconless_collapsible: function() {
- // If the collapsible passed to toggle_collapsible() has no
- // icon, toggle_collapsible() will raise an error.
- var invalid_collapsible = Y.Node.create(
- '<fieldset class="collapsible"> ' +
- ' <div class="collapseWrapper">' +
- ' <p>No icon!</p>' +
- ' </div>' +
- '</fieldset>');
-
- Y.lp.toggle_collapsible(invalid_collapsible);
- },
-
- test_activate_collapsibles_doesnt_fail_on_legendless_collapsible:
- function() {
- // If a collapsible doesn't have a wrapper div,
- // activate_collapsibles() won't fail, since there might be
- // other collapsibles on the page.
- var invalid_collapsible = Y.Node.create(
- '<fieldset class="collapsible"> ' +
- ' <img src="#" class="collapseIcon" />' +
- ' <p>No legend!</p>' +
- '</fieldset>');
-
- var valid_collapsible = this.container.one('.collapsible');
- this.container.insertBefore(invalid_collapsible, valid_collapsible);
- Y.lp.activate_collapsibles();
-
- // The standard, valid collapsible is still set up correctly.
- Assert.isNotNull(
- valid_collapsible.one('.collapseWrapper'),
- "activate_collapsibles() should have added a wrapper div for " +
- "the valid collapsible.");
- },
-
- test_activate_collapsibles_sets_up_multiple_collapsibles: function() {
- // If there are several collapsibles on a page,
- // activate_collapsibles() will activate them all.
- for (i = 0; i < 5; i++) {
- var new_collapsible =
- this.default_fieldset_node.cloneNode(
- this.default_fieldset_node);
-
- this.container.appendChild(new_collapsible);
- }
-
- Y.lp.activate_collapsibles();
- Y.all('.collapsible').each(function(collapsible) {
- Assert.isNotNull(
- collapsible.one('.collapseWrapper'),
- "activate_collapsibles() should have added a wrapper div " +
- "to all collapsibles.");
- });
- },
-
- test_activate_collapsibles_handles_no_collapsibles: function() {
- // If there are no collapsibles in a page,
- // activate_collapsibles() will still complete successfully.
- this.container.set('innerHTML', '');
- Y.lp.activate_collapsibles();
- },
-
- test_activate_collapsibles_removes_existing_anchors: function() {
- // If there's already an anchor within a collapsible fieldset's
- // legend it will be removed before its contents are moved into
- // the new anchor created by activate_collapsibles(). This is to
- // avoid leaving clickable-through links in the collapsible
- // header.
- var new_collapsible = Y.Node.create(
- '<fieldset class="collapsible"> ' +
- ' <legend>' +
- ' <a id="should-be-removed"' +
- ' href="http://launchpad.net">' +
- ' With a link in it' +
- ' </a>' +
- ' </legend>' +
- ' <p>Some contents</p>' +
- '</fieldset>');
-
- this.container.set('innerHTML', '');
- this.container.appendChild(new_collapsible);
- Y.lp.activate_collapsibles();
-
- var collapsible = this.container.one('.collapsible');
- Assert.isNull(
- this.container.one('#should-be-removed'),
- "The should-be-removed link should have been removed");
- },
-
- test_activate_collapsibles_doesnt_reactivate_collapsibles: function() {
- // If activate_collapsibles() has already been called, calling
- // it again won't break the existing collapsibles.
- Y.lp.activate_collapsibles();
- var collapsible = this.container.one('.collapsible');
- var anchor = collapsible.one('a');
- var span = anchor.one('span');
- var original_span_contents = span.get('innerHTML');
- var wrapper = collapsible.one('.collapseWrapper');
- var original_wrapper_contents = wrapper.get('innerHTML');
-
- // Calling activate_collapsibles() shouldn't break things.
- Y.lp.activate_collapsibles();
- collapsible = this.container.one('.collapsible');
- anchor = collapsible.one('a');
- span = anchor.one('span');
- wrapper = collapsible.one('.collapseWrapper');
-
- Assert.isNotNull(
- anchor, "Existing collapsibles' anchors should be intact.");
-
- var icon = anchor.one('img');
- Assert.isNotNull(
- icon,
- "Existing collapsibles' icons should be intact.");
-
- Assert.areEqual(
- original_span_contents, span.get('innerHTML'),
- "Existing collapsibles' spans should be intact.");
-
- Assert.isNotNull(
- wrapper,
- "Existing collapsibles' wrapper divs should be intact.");
- }
-}));
-
-// Lock, stock, and two smoking barrels.
-var handle_complete = function(data) {
- window.status = '::::' + JSON.stringify(data);
- };
-Y.Test.Runner.on('complete', handle_complete);
-Y.Test.Runner.add(suite);
-
-var yui_console = new Y.Console({
- newestOnTop: false
-});
-yui_console.render('#log');
-
-Y.on('domready', function() {
- Y.Test.Runner.run();
-});
-});
=== modified file 'lib/lp/bugs/templates/bugtarget-macros-filebug.pt'
--- lib/lp/bugs/templates/bugtarget-macros-filebug.pt 2011-04-27 14:46:58 +0000
+++ lib/lp/bugs/templates/bugtarget-macros-filebug.pt 2011-07-07 16:52:35 +0000
@@ -64,8 +64,9 @@
<tr>
<td colspan="2">
- <fieldset id="filebug-extra-options" class="collapsible collapsed">
+ <fieldset id="filebug-extra-options" class="collapsible">
<legend>Extra options</legend>
+ <div class="unseen">
<table>
<tal:status
define="widget nocall:view/widgets/status|nothing"
@@ -93,6 +94,7 @@
</table>
<metal:attachment-form
use-macro="context/@@bug-attachment-macros/attachment-form" />
+ </div>
</fieldset>
</td>
</tr>
=== modified file 'lib/lp/code/templates/branch-register-merge.pt'
--- lib/lp/code/templates/branch-register-merge.pt 2010-12-20 17:45:45 +0000
+++ lib/lp/code/templates/branch-register-merge.pt 2011-07-07 16:52:35 +0000
@@ -30,8 +30,9 @@
<td colspan="2">
<fieldset id="mergeproposal-extra-options"
- class="collapsible collapsed">
+ class="collapsible">
<legend>Extra options</legend>
+ <div class="unseen"><!-- hidden by default -->
<table class="extra-options">
<tal:widget define="widget nocall:view/widgets/commit_message">
@@ -49,6 +50,7 @@
</table>
+ </div>
</fieldset>
</td>
=== modified file 'lib/lp/code/templates/sourcepackagerecipe-related-branches.pt'
--- lib/lp/code/templates/sourcepackagerecipe-related-branches.pt 2011-06-27 15:25:02 +0000
+++ lib/lp/code/templates/sourcepackagerecipe-related-branches.pt 2011-07-07 16:52:35 +0000
@@ -1,11 +1,11 @@
<fieldset id="related-branches"
xmlns:tal="http://xml.zope.org/namespaces/tal"
- class="collapsible collapsed" style="width: 60em"
+ class="collapsible" style="width: 60em"
tal:define="seriesBranches view/related_series_branch_info;
packageBranches view/related_package_branch_info"
tal:condition="python: seriesBranches or packageBranches">
<legend>Related branches</legend>
- <div class="extra-options">
+ <div class="extra-options unseen">
<div tal:condition="packageBranches" id="related-package-branches">
<h2>Source package branches</h2>
=== modified file 'lib/lp/registry/templates/pillar-involvement-portlet.pt'
--- lib/lp/registry/templates/pillar-involvement-portlet.pt 2010-11-12 21:21:34 +0000
+++ lib/lp/registry/templates/pillar-involvement-portlet.pt 2011-07-07 16:52:35 +0000
@@ -73,12 +73,17 @@
</div>
<div id="show-hide-configs"
- tal:attributes="class
- python: 'collapsible collapsed'
- if view.registration_done
- else 'collapsible'">
- <div class="config-options"
- style="margin-bottom: 0.5em">Configuration options</div>
+ class="collapsible">
+ <legend>
+ <div class="config-options" style="margin-bottom: 0.5em;">
+ Configuration options
+ </div>
+ </legend>
+ <div
+ tal:attributes="class
+ python: 'expanded'
+ if not view.registration_done
+ else ''">
<table
tal:condition="view/configuration_links"
style="width: 100%; padding-top: 1em"
@@ -96,6 +101,7 @@
</tr>
</tal:item>
</table>
+ </div>
</div>
</tal:show-registration>
=== modified file 'lib/lp/registry/templates/product-files.pt'
--- lib/lp/registry/templates/product-files.pt 2011-03-04 00:39:17 +0000
+++ lib/lp/registry/templates/product-files.pt 2011-07-07 16:52:35 +0000
@@ -67,9 +67,9 @@
<div tal:attributes="id release/version/fmt:css-id/release-information-"
tal:condition="python: release.release_notes or release.changelog">
- <fieldset class="collapsible collapsed" style="padding: 0px;">
+ <fieldset class="collapsible" style="padding: 0px;">
<legend>Release information</legend>
-
+ <div class="unseen">
<div tal:condition="release/release_notes">
<strong>Release notes:</strong>
<div style="margin-bottom: 0px;"
@@ -88,6 +88,7 @@
ProductRelease.changelog.
</div>
</div>
+ </div>
</fieldset>
</div>
<div>
=== modified file 'lib/lp/registry/templates/productrelease-portlet-data.pt'
--- lib/lp/registry/templates/productrelease-portlet-data.pt 2011-02-24 14:47:10 +0000
+++ lib/lp/registry/templates/productrelease-portlet-data.pt 2011-07-07 16:52:35 +0000
@@ -81,11 +81,11 @@
<h2>Changelog <a tal:replace="structure view/release/menu:context/edit/fmt:icon" /></h2>
- <fieldset class="collapsible collapsed" style="padding: 0px;"
+ <fieldset class="collapsible" style="padding: 0px;"
tal:condition="view/release/changelog">
<legend>View the full changelog</legend>
- <div id="changelog" style="margin-bottom: 0px;"
+ <div id="changelog" class="unseen" style="margin-bottom: 0px;"
tal:content="structure view/release/changelog/fmt:obfuscate-email/fmt:text-to-html">
ProductRelease.changelog.
</div>
Follow ups