use crate::tests::prelude::*;
track_file!("ref/asciidoc-lang/docs/modules/blocks/pages/collapsible.adoc");
non_normative!(
r#"
= Collapsible Blocks
You can designate block content to be revealed or hidden on interaction using the collapsible option and its companion, the open option.
When the AsciiDoc source is converted to HTML, this block gets mapped to a disclosure summary element (i.e., a summary/details pair).
If the output format does not support this interaction, it may be rendered as an unstyled block (akin to an open block).
"#
);
#[test]
fn collapsible_block_syntax() {
non_normative!(
r#"
== Collapsible block syntax
"#
);
verifies!(
r#"
You make block content collapsible by specifying the `collapsible` option on the example structural container.
This option changes the block from an example block to a collapsible block.
.Collapsible block syntax
[#ex-collapsible]
----
include::example$collapsible.adoc[tag=basic]
----
In the output, the content of this block is hidden until the reader clicks the default title, "`Details`".
The result of <<ex-collapsible>> is displayed below.
include::example$collapsible.adoc[tag=basic]
Like other blocks, the collapsible block recognizes the `id` and `role` attributes.
"#
);
let doc = Parser::default().parse(
"[%collapsible]\n====\nThis content is only revealed when the user clicks the block title.\n====",
);
assert_css(&doc, "details", 1);
assert_css(&doc, ".exampleblock", 0);
assert_xpath(
&doc,
"//details/summary[@class=\"title\"][text()=\"Details\"]",
1,
);
assert_css(&doc, "details > div.content", 1);
assert_xpath(
&doc,
"//details/div[@class=\"content\"]//p[text()=\"This content is only revealed when the user clicks the block title.\"]",
1,
);
assert_xpath(&doc, "//details[@open]", 0);
let doc = Parser::default().parse("====\nNot collapsible.\n====");
assert_css(&doc, "details", 0);
assert_css(&doc, ".exampleblock", 1);
let doc = Parser::default().parse("[#disclosure.scary%collapsible]\n====\nHidden.\n====");
assert_xpath(&doc, "//details[@id=\"disclosure\"]", 1);
assert_css(&doc, "details.scary", 1);
}
#[test]
fn collapsible_paragraph_syntax() {
non_normative!(
r#"
== Collapsible paragraph syntax
"#
);
verifies!(
r#"
If the content of the block is only a single paragraph, you can use the example paragraph style instead of the example structural container to make a collapsible paragraph.
.Collapsible paragraph syntax
[#ex-collapsible-paragraph]
----
include::example$collapsible.adoc[tag=paragraph]
----
In the output, the content of this block is hidden until the reader clicks the default title, "`Details`".
The result of <<ex-collapsible-paragraph>> is displayed below.
include::example$collapsible.adoc[tag=paragraph]
"#
);
let doc = Parser::default().parse(
"[example%collapsible]\nThis content is only revealed when the user clicks the block title.",
);
assert_css(&doc, "details", 1);
assert_xpath(
&doc,
"//details/summary[@class=\"title\"][text()=\"Details\"]",
1,
);
assert_xpath(
&doc,
"//details/div[@class=\"content\"][normalize-space(text())=\"This content is only revealed when the user clicks the block title.\"]",
1,
);
let doc = Parser::default().parse("[example%collapsible]\nThis is *bold*.");
assert_xpath(
&doc,
"//details/div[@class=\"content\"]/strong[text()=\"bold\"]",
1,
);
let doc = Parser::default().parse(
"[%collapsible]\nThis content is only revealed when the user clicks the block title.",
);
assert_css(&doc, "details", 0);
assert_css(&doc, ".paragraph", 1);
}
#[test]
fn customize_the_toggle_text() {
non_normative!(
r#"
== Customize the toggle text
"#
);
verifies!(
r#"
If you want to customize the text that toggles the display of the collapsible content, specify a title on the block or paragraph.
.Collapsible block with custom title
[#ex-collapsible-with-title]
----
include::example$collapsible.adoc[tag=title]
----
The result of <<ex-collapsible-with-title>> is displayed below.
include::example$collapsible.adoc[tag=title]
Notice that even though this block has a title, it's not numbered and does not have a caption prefix.
That's because it's not an example block and thus does not get a numbered caption prefix like an example block would.
"#
);
let doc = Parser::default()
.parse(".Click to reveal the answer\n[%collapsible]\n====\nThis is the answer.\n====");
assert_xpath(
&doc,
"//details/summary[@class=\"title\"][text()=\"Click to reveal the answer\"]",
1,
);
assert_css(&doc, "div.title", 0);
}
#[test]
fn default_to_open() {
non_normative!(
r#"
== Default to open
"#
);
verifies!(
r#"
If you want the collapsible block to be open by default, specify the `open` option as well.
.Collapsible block that defaults to open
[#ex-collapsible-open]
----
include::example$collapsible.adoc[tag=open]
----
The result of <<ex-collapsible-open>> is displayed below.
include::example$collapsible.adoc[tag=open]
"#
);
let doc = Parser::default().parse(
".Too much detail? Click here.\n[%collapsible%open]\n====\nThis content is revealed by default.\n\nIf it's taking up too much space, the reader can hide it.\n====",
);
assert_xpath(&doc, "//details[@open]", 1);
assert_xpath(
&doc,
"//details/summary[@class=\"title\"][text()=\"Too much detail? Click here.\"]",
1,
);
assert_css(&doc, "details > div.content > div.paragraph", 2);
}
#[test]
fn use_as_an_enclosure() {
non_normative!(
r#"
== Use as an enclosure
"#
);
verifies!(
r#"
Much like the open block, the collapsible block is an enclosure.
If you want to make other types of blocks collapsible, such as an listing block, you can nest the block inside the collapsible block.
.Collapsible block that encloses a literal block
[#ex-collapsible-nested]
----
include::example$collapsible.adoc[tag=nested]
----
The result of <<ex-collapsible-nested>> is displayed below.
include::example$collapsible.adoc[tag=nested]
Since the toggle text acts as the block title, you may decide to not put a title on the nested block, as in this example.
"#
);
let doc = Parser::default().parse(
".Show stacktrace\n[%collapsible]\n====\n....\nError: Content repository not found (url: https://git.example.org/repo.git)\n at transformGitCloneError\n....\n====",
);
assert_css(&doc, "details", 1);
assert_xpath(
&doc,
"//details/summary[@class=\"title\"][text()=\"Show stacktrace\"]",
1,
);
assert_css(&doc, "details > div.content .literalblock", 1);
assert_css(&doc, "details > div.content .literalblock pre", 1);
}