f41b982009-05-07Martin Stjernholm // This is a roxen module. Copyright © 1999 - 2009, Roxen IS.
77c05a1999-12-08Martin Nilsson //
6cd9d71999-08-05Martin Nilsson 
0917d32013-03-04Anders Johansson constant cvs_version = "$Id$";
cc96fe2001-01-21Martin Nilsson constant thread_safe = 1;
6cd9d71999-08-05Martin Nilsson  #include <module.h> inherit "module";
b3281f2000-09-10Martin Nilsson constant module_type = MODULE_TAG;
bc0fa02001-03-08Per Hedbor constant module_name = "Tags: Folding lists";
59ae152000-04-06Mattias Wingstedt constant module_doc = "Provides the &lt;foldlist&gt; tag, which is used to " "build folding lists. The folding lists work like <tt>&lt;dl&gt;</tt> lists " "where each item can be folded or unfolded.";
6cd9d71999-08-05Martin Nilsson 
b08d082000-05-01Martin Nilsson TAGDOCUMENTATION;
cfe42b1999-12-07Martin Nilsson #ifdef manual
65aa322000-02-07Kenneth Johansson constant tagdoc=([
fe98131999-11-24Martin Nilsson 
ce8fb02001-09-21Johan Sundström "foldlist":({#"<desc type='cont'><p><short hide='hide'>
5eff412000-05-02Kenneth Johansson  This tag is used to build folding lists, that are like &lt;dl&gt; lists,
baf02c2000-04-15Per Hedbor  but where each element can be unfolded.</short>This tag is used to build folding lists, that are like <tag>dl</tag> lists, but where each element can be unfolded. The tags used to build the lists
ce8fb02001-09-21Johan Sundström  elements are <tag>ft</tag> and <tag>fd</tag>.</p></desc>
fe98131999-11-24Martin Nilsson 
9b03652001-03-07Kenneth Johansson <attr name='unfolded'><p> Will make all the elements in the list unfolded by default.</p>
65aa322000-02-07Kenneth Johansson </attr>
ae83ae2001-12-07Martin Stjernholm  <attr name='foldedsrc'><p> The image to use for folded items. The default is '/internal-roxen-unfold'.</p> </attr> <attr name='unfoldedsrc'><p> The image to use for unfolded items. The default is '/internal-roxen-fold'.</p> </attr>",
65aa322000-02-07Kenneth Johansson 
ce8fb02001-09-21Johan Sundström ([ "ft":({#"<desc type='cont'><p>
65aa322000-02-07Kenneth Johansson This tag is used within the foldlist tag. The contents of this container, that is not within an fd, tag will be visible both when the
9b03652001-03-07Kenneth Johansson element is folded and unfolded.</p></desc>
65aa322000-02-07Kenneth Johansson 
9b03652001-03-07Kenneth Johansson <attr name='folded'><p> Will make this element folded by default. Overrides an unfolded attribute set in the foldlist tag.</p>
65aa322000-02-07Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='unfolded'><p> Will make this element unfolded by default.</p>
ae83ae2001-12-07Martin Stjernholm </attr> <attr name='foldedsrc'><p> The image to use for folded items. Overrides the 'foldedsrc' attribute in <tag>tablist</tag> for this item.</p> </attr> <attr name='unfoldedsrc'><p> The image to use for unfolded items. Overrides the 'foldedsrc' attribute in <tag>tablist</tag> for this item.</p>
ce8fb02001-09-21Johan Sundström </attr>",
65aa322000-02-07Kenneth Johansson 
ce8fb02001-09-21Johan Sundström ([ "fd":#"<desc type='cont'><p>
9b03652001-03-07Kenneth Johansson  The contents of this container will only be visible when the element it is written in is unfolded.</p> </desc>
5eff412000-05-02Kenneth Johansson  <ex> <foldlist> <ft> Heading1 <fd>Contents 1</fd> </ft> <ft> Heading2 <fd>Contents 2</fd> </ft> </foldlist>
ce8fb02001-09-21Johan Sundström </ex>" ])
fe98131999-11-24Martin Nilsson  })])
cfe42b1999-12-07Martin Nilsson })]); #endif
fe98131999-11-24Martin Nilsson 
5eff412000-05-02Kenneth Johansson 
b08d082000-05-01Martin Nilsson string encode_url(array states, RequestID id){ object state=id->misc->foldlist->state;
fe98131999-11-24Martin Nilsson 
b08d082000-05-01Martin Nilsson  int value, q;
6cd9d71999-08-05Martin Nilsson  foreach(states, int tmp) {
b08d082000-05-01Martin Nilsson  value+=tmp*(2->pow(q)); q+=2;
fe98131999-11-24Martin Nilsson  }
b08d082000-05-01Martin Nilsson  value=(value<<1)+1;
96a00d2002-01-24Martin Stjernholm  return state->encode_revisit_url (id, value);
6cd9d71999-08-05Martin Nilsson }
b08d082000-05-01Martin Nilsson class TagFoldlist { inherit RXML.Tag; constant name = "foldlist"; class TagFD { inherit RXML.Tag; constant name = "fd"; class Frame { inherit RXML.Frame; int show; array do_enter(RequestID id) { show=id->misc->foldlist_show; if(show) do_iterate=0; else do_iterate=-1; return 0; } int do_iterate; array do_return(RequestID id) { if(show)
1a02362003-09-11Henrik Grubbström (Grubba)  result="<dt><dd>"+content+"</dd></dt>";
b08d082000-05-01Martin Nilsson  else
1a02362003-09-11Henrik Grubbström (Grubba)  result="";
b08d082000-05-01Martin Nilsson  return 0; }
6cd9d71999-08-05Martin Nilsson  }
b08d082000-05-01Martin Nilsson  }
6cd9d71999-08-05Martin Nilsson 
b08d082000-05-01Martin Nilsson  class TagFT { inherit RXML.Tag; constant name = "ft"; class Frame { inherit RXML.Frame; int index, show; int set_def(RequestID id) { if (args->unfold) return 1; if (args->fold) return 0; return id->misc->foldlist->def; } array do_enter(RequestID id) { index=id->misc->foldlist->counter++; if(sizeof(id->misc->foldlist->states)>index) switch(id->misc->foldlist->states[index]) { case 0: show = set_def(id); break; case 1: show = 0; break; case 2: show = 1; break; } else { id->misc->foldlist->states+=({ 0 }); show=set_def(id); } id->misc->foldlist_show=show; return 0; } array do_return(RequestID id) { array states=copy_value(id->misc->foldlist->states); states[index]=!show+1; result="<dt><a target=\"_self\" href=\""+ encode_url(states, id)+ "\"><img src=\""+ (args[(show?"un":"")+"foldedsrc"]||id->misc->foldlist[(show?"u":"")+"fsrc"])+ "\" border=\"0\" alt=\""+({ "+", "-" })[show]+"\" /></a>"+
1a02362003-09-11Henrik Grubbström (Grubba)  content+"</dt>";
b08d082000-05-01Martin Nilsson  return 0; } } }
dd9a412001-08-24Martin Stjernholm  // This tag set can probably be shared, but I don't know for sure. /mast RXML.TagSet internal = RXML.TagSet(this_module(), "foldlist", ({ TagFT(), TagFD() }) );
b08d082000-05-01Martin Nilsson  class Frame { inherit RXML.Frame; RXML.TagSet additional_tags = internal; mapping foldlist; string state_id; array do_enter(RequestID id) { // The initial state int def=!!args->unfolded; // Find out environment foldlist=id->misc->foldlist; string hist=""; if(foldlist && foldlist->hist) { hist=foldlist->hist; if(foldlist->cnt > 15) hist+=":"; hist+=sprintf("%x",foldlist->cnt); } else id->misc->foldlist_depth++; // Register ourselfs as state consumers and incorporate our initial state.
398eee2001-01-06Martin Nilsson  state_id = (args->name || "fl")+":"+id->misc->foldlist_depth+":"+hist;
cd5d732001-01-26Martin Nilsson  StateHandler.Page_state state=StateHandler.Page_state(id); state_id = state->register_consumer(state_id);
f9b6cf2001-02-10Martin Nilsson  if(id->real_variables->__state && !state->uri_decode(id->real_variables->__state[0]))
b08d082000-05-01Martin Nilsson  RXML.run_error("Error in state."); //Get our real state // 00 unknown // 01 folded // 10 unfolded array(int) states=({});
398eee2001-01-06Martin Nilsson  int istates=state->get();
b08d082000-05-01Martin Nilsson  // werror("istates: %d\n",istates); if(istates) istates=istates>>1; while(istates) { states+=({ istates & 3 }); istates=istates >> 2; } while(sizeof(states) && states[-1]==0) states=states[..sizeof(states)-2]; // Export our findings id->misc->foldlist=(["states":states, "state":state, "def":def, "cnt":0, "hist":hist, "fsrc":args->foldedsrc||"/internal-roxen-unfold", "ufsrc":args->unfoldedsrc||"/internal-roxen-fold" ]); return 0; } array do_return(RequestID id) { id->misc->foldlist=foldlist; result = (id->misc->debug?"<!-- "+state_id+" -->\n":"")+ "<dl>"+content+"</dl>\n"; m_delete(id->misc, "foldlist_show"); return 0; } }
6cd9d71999-08-05Martin Nilsson }