| 1 | """An expandable/collapsible box of wiki content. |
|---|
| 2 | |
|---|
| 3 | Can by styled with the css classes 'expander', 'open', 'closed'. |
|---|
| 4 | Additional css classes can be added with a 'class' parameter. |
|---|
| 5 | The title can use inline wiki format. |
|---|
| 6 | |
|---|
| 7 | Example: |
|---|
| 8 | {{{#!Expander title='An Outrageous Claim' state=open |
|---|
| 9 | An in detail elaboration of this outrageous claim, using full wiki syntax. |
|---|
| 10 | }}} |
|---|
| 11 | """ |
|---|
| 12 | from string import Template |
|---|
| 13 | from genshi.builder import tag |
|---|
| 14 | from trac.wiki.macros import WikiMacroBase |
|---|
| 15 | from trac.wiki import format_to_html, format_to_oneliner |
|---|
| 16 | |
|---|
| 17 | t = Template('$state expander$extra') |
|---|
| 18 | s = Template('display: $display') |
|---|
| 19 | script = ("s=nextSibling.style.display=='none';nextSibling.style.display=s?'block':'none';" |
|---|
| 20 | "c = parentNode.getAttribute('class');" |
|---|
| 21 | "parentNode.setAttribute('class',c.replace(s?/^closed/:/^open/,s?'open':'closed'))") |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | class ExpanderMacro(WikiMacroBase): |
|---|
| 25 | |
|---|
| 26 | def expand_macro(self, formatter, name, content, args): |
|---|
| 27 | cssclass = args.get('class', None) |
|---|
| 28 | cssclass = (cssclass and ' ' + cssclass) or '' |
|---|
| 29 | title = args.get('title', 'Title') |
|---|
| 30 | state = args.get('state', 'closed') |
|---|
| 31 | display = state == 'closed' and 'none' or 'block' |
|---|
| 32 | return tag.div(tag.h6(format_to_oneliner(self.env, formatter.context, title), |
|---|
| 33 | onclick=script), |
|---|
| 34 | tag.div(format_to_html(self.env, formatter.context, content), |
|---|
| 35 | style=s.substitute(display=display)), |
|---|
| 36 | class_=t.substitute(state=state, extra=cssclass)) |
|---|