Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><br/>
<span macro='preview text'></span>
<!--}}}-->
/***
|Name:|ExtentTagButtonPlugin|
|Description:|Adds a New tiddler button in the tag drop down|
|Version:|3.2 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#ExtendTagButtonPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
window.onClickTag_mptw_orig = window.onClickTag;
window.onClickTag = function(e) {
window.onClickTag_mptw_orig.apply(this,arguments);
var tag = this.getAttribute("tag");
var title = this.getAttribute("tiddler");
// Thanks Saq, you're a genius :)
var popup = Popup.stack[Popup.stack.length-1].popup;
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
wikify("<<newTiddler label:'New tiddler' tag:'"+tag+"'>>",createTiddlyElement(popup,"li"));
return false;
}
//}}}
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
config.formatters.push(
{
keywords : {
"var":"blue",
"try":"blue",
"catch":"blue",
"if":"blue",
"else":"blue",
"for":"blue",
"while":"blue",
"do":"blue",
"function":"blue",
"Function":"blue",
"String":"blue",
"Object":"blue",
"RegExp":"blue",
"Array":"blue",
"Math":"blue",
"Date":"blue",
";":"blue",
"+":"red",
"-":"red",
"*":"red",
"/":"red",
"%":"red",
"^":"red",
"&":"red",
"|":"red",
"!":"red",
"~":"red",
"=":"red",
"<":"red",
">":"red",
"false":"DarkBlue",
"true":"DarkBlue",
"window":"DarkBlue",
"document":"DarkBlue",
"alert":"IndianRed",
"eval":"IndianRed",
"setInterval":"IndianRed",
"setTimeout":"IndianRed",
"toString":"IndianRed",
"write":"IndianRed"
},
match: "<js\\n",
lookahead: "<js\\n((?:.|\\n)*?)\\njs>",
handler: function(w)
{
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
{
var e = createTiddlyElement(w.output,"pre");
var str = lookaheadMatch[1];
var Reg = /(\/\/.*?$)|(\/\*(.|\n)*?\*\/)|[']{2}|('.*?[^\\]')|["]{2}|(".*?[^\\]")|\w+|[\s\n]+|./mg;
var parts = str.match(Reg);
for(var i = 0; i < parts.length; i++){
if(parts[i].match(/^[\s\n]/))parts[i] = parts[i].replace(/\t/g," ").replace(/\n/g,"<br/>").replace(/\r/g,"");
else if(parts[i].match(/^(?:\/\/)|(?:\/\*)/))parts[i] = "<span style=\"color:green;\">"+parts[i].htmlEncode().replace(/\\n/g,"<br/>")+"</span>";
else if(parts[i].charAt(0)=="\""||parts[i].charAt(0)=="'")parts[i] = "<span style=\"color:teal;\">"+parts[i].htmlEncode()+"</span>";
else if(this.keywords[parts[i]])parts[i] = "<span style=\"color:"+this.keywords[parts[i]]+";\">"+parts[i].htmlEncode()+"</span>";
}
e.innerHTML = parts.join("");
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
}
}
);
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
!Tag Menu
<<tagsTree FSubScript "" 2 6 index label>>
Type the text for 'New Tiddler'
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='sidebar'>
<div id='mainMenu' refresh='content' force='true' tiddler='MainMenu'></div>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/***
|Name|PreviewPlugin|
|Source|http://www.TiddlyTools.com/#PreviewPlugin|
|Documentation|http://www.TiddlyTools.com/#PreviewPluginInfo|
|Version|1.8.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|add key-by-key wikified preview to any textarea input field|
Provides key-by-key ''LIVE PREVIEW'' of //formatted// tiddler content as you type input into a textarea (multi-line) edit field.
!!!!!Documentation
>see [[PreviewPluginInfo]]
!!!!!Configuration
<<<
Automatically freeze preview updates when a tiddler takes more than <<option txtPreviewAutoFreeze>> milliseconds to render.
<<<
!!!!!Revisions
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.11.18 [1.8.1] in config.commands.previewTiddler, changed alt command text to use character-based "psuedo-checkbox" instead of embedded html fragment
2007.09.27 [1.8.0] split TidIDE preview functionality into separate stand-alone plugin (see [[TidIDEPlugin]]).
|please see [[TidIDEPluginInfo]] for additional revision details|
2006.04.15 [0.5.0] Initial ALPHA release. Converted from inline script.
<<<
!!!!!Code
***/
// // version info
//{{{
version.extensions.PreviewPlugin= {major: 1, minor: 8, revision: 1, date: new Date(2007,11,18)};
//}}}
// // macro definition
//{{{
if (config.options.txtPreviewAutoFreeze==undefined)
config.options.txtPreviewAutoFreeze=250; // limit (in milliseconds) for auto-freezing preview display
config.macros.preview = {
renderMsg: "rendering preview...",
timeoutMsg: " (> %0ms)",
freezeMsg: " - preview is frozen. Press [refresh] to re-display.",
handler: function(place,macroName,params) {
var hide=params[0]=="hide"; if (hide) params.shift();
var field=params[0];
var height=params[1]; if (!height) height=15;
var here=this.findContainingForm(place);
if (!here) here=story.findContainingTiddler(place);
if (!here) here=place.parentNode;
if (!here) here=place;
var elems=here.getElementsByTagName("textarea");
if (field) for (var e=0; e<elems.length; e++) // find matching textarea (by fieldname)
if (elems[e].getAttribute("edit")==field) var ta=elems[e];
else
if (elems.length) var ta=elems[elems.length-1]; // default to last rendered text area
if (!ta) {
var elems=here.getElementsByTagName("input");
if (field) for (var e=0; e<elems.length; e++) // find matching input field (by fieldname)
if (elems[e].getAttribute("edit")==field) var ta=elems[e];
else
if (elems.length) var ta=elems[elems.length-1]; // default to last rendered input field
}
if (!ta) return false; // no textarea or input field found... do nothing...
var id=(new Date().getTime()).toString()+Math.random(); // unique instance ID
ta.id=id+"_edit";
ta.setAttribute("previewid",id+"_preview");
ta.saved_onkeyup=ta.onkeyup;
ta.onkeyup=function(ev) {
if (this.saved_onkeyup) this.saved_onkeyup.apply(this,arguments);
config.macros.preview.render(this.id,this.getAttribute("previewid"));
}
var html=this.html.replace(/%previd%/g,id+"_preview")
html=html.replace(/%srcid%/g,id+"_edit");
html=html.replace(/%hide%/g,hide?"none":"block");
html=html.replace(/%limit%/g,config.options.txtPreviewAutoFreeze);
html=html.replace(/%frozen%/g,hide?"checked":"");
html=html.replace(/%height%/g,height);
html=html.replace(/%halfheight%/g,height/2);
createTiddlyElement(place,"span").innerHTML=html;
this.render(id+"_edit",id+"_preview");
},
findContainingForm: function(e) {
while (e && e.nodeName.toLowerCase()!="form") e=e.parentNode;
return e;
},
render: function(srcid,previd,force) {
var value=document.getElementById(srcid).value;
var panel=document.getElementById(previd);
var f=this.findContainingForm(panel);
if (!f || (f.freeze.checked && !force)) return;
var p=panel.firstChild; var d=f.domview; var h=f.htmlview; if (!p||!d||!h) return;
p.innerHTML="";
f.status.value=this.renderMsg;
var start=new Date();
wikify(value.replace(/\r/g,''),p);
var end=new Date();
this.renderDOM(previd);
this.renderHTML(previd);
f.status.value="elapsed: "+(end-start+1)+"ms";
// automatically suspend preview updates for slow rendering tiddlers
if (end-start+1>config.options.txtPreviewAutoFreeze) {
f.freeze.checked=true;
f.status.value+=this.timeoutMsg.format([config.options.txtPreviewAutoFreeze]);
}
if (f.freeze.checked) f.status.value+=this.freezeMsg;
},
renderDOM: function(id) {
var panel=document.getElementById(id);
var f=this.findContainingForm(panel); if (!f) return;
var p=panel.firstChild; var d=f.domview; var h=f.htmlview; if (!p||!d||!h) return;
var height=p.getAttribute("height");
p.style.height=((f.dom.checked||f.html.checked)?height/2:height)+"em";
if (f.dom.checked) d.value=this.getNodeTree(p,"| ");
if (!d.style||!h.style) return;
d.style.height=height/2+"em";
d.style.display=f.dom.checked?"inline":"none";
d.style.width=f.html.checked?"49.5%":"100%";
h.style.width=f.dom.checked?"49.5%":"100%";
},
renderHTML: function(id) {
var panel=document.getElementById(id);
var f=this.findContainingForm(panel); if (!f) return;
var p=panel.firstChild; var d=f.domview; var h=f.htmlview; if (!p||!d||!h) return;
var height=p.getAttribute("height");
p.style.height=((f.dom.checked||f.html.checked)?height/2:height)+"em";
if (f.html.checked) h.value=this.formatHTML(p.innerHTML);
if (!h.style||!d.style) return;
h.style.height=height/2+"em";
h.style.display=f.html.checked?"inline":"none";
h.style.width=f.dom.checked?"49.5%":"100%";
d.style.width=f.html.checked?"49.5%":"100%";
},
formatHTML: function(txt) {
if (config.browser.isIE) return txt; // BYPASS - 4/24/2006 due to IE hang problem. Will fix later...
var out="";
var indent="";
var level=0;
for (var i=0;i<txt.length;i++) {
var c=txt.substr(i,1);
if (c=="<") {
if (txt.substr(i+1,1)=="/") indent=indent.substr(0,indent.length-2);
out+="\n"+indent;
if (txt.substr(i+1,1)!="/" && txt.substr(i+1,3)!="br>" && txt.substr(i+1,2)!="p>" && txt.substr(i+1,3)!="hr>") indent+=" ";
}
out+=c;
if (c=="\n")
out+=indent;
if (c==">" && txt.substr(i+1,1)!="<")
out+="\n"+indent;
}
return out;
},
getNodeTree: function(theNode,theIndent,showPath,inline,thePrefix,thePath)
{
if (!theNode) return "";
if (!thePrefix) thePrefix="";
if (!thePath) thePath="";
var mquote='"'+(inline?"{{{":"");
var endmquote=(inline?"}}}":"")+'"';
// generate output for this node
var out = thePrefix;
if (showPath && thePath.length)
out += (inline?"//":"")+thePath.substr(1)+":"+(inline?"//":"")+"\r\n"+thePrefix;
if (theNode.className=="DOMViewer")
return out+'[DOMViewer]\r\n'; // avoid self-referential recursion
out += (inline?"''":"")+theNode.nodeName.toUpperCase()+(inline?"''":"");
if (theNode.nodeName=="#text")
out += ' '+mquote+theNode.nodeValue.replace(/\n/g,'\\n')+endmquote;
if (theNode.className)
out += ' class='+mquote+theNode.className+endmquote;
if (theNode.type)
out += ' type='+mquote+theNode.type+endmquote;
if (theNode.id)
out += ' id='+mquote+theNode.id+endmquote;
if (theNode.name)
out += " "+theNode.name+(theNode.value?"="+mquote+theNode.value+endmquote:"");
if (theNode.href)
out += ' href='+mquote+theNode.href+endmquote;
if (theNode.src)
out += ' src='+mquote+theNode.src+endmquote;
if (theNode.attributes && theNode.getAttribute("tiddlyLink")!=undefined)
out += ' tiddler='+mquote+theNode.getAttribute("tiddlyLink")+endmquote;
out += "\r\n";
// recursively generate output for child nodes
thePath=thePath+"."+theNode.nodeName.toLowerCase();
thePrefix=theIndent+thePrefix;
for (var i=0;i<theNode.childNodes.length;i++)
{
var thisChild=theNode.childNodes.item(i);
var theNum=(inline?"~~":"(")+(i+1)+(inline?"~~":")");
out += this.getNodeTree(thisChild,theIndent,showPath,inline,thePrefix,thePath+theNum);
}
return out;
},
html: " <form style='width:100%;border:1px solid black;'><span id='%previd%' editID='%srcid%' style='display:%hide%'><div class='viewer' \
height='%height%' style='margin:0;margin-top:.5em;height:%height%em;overflow:auto;white-space:normal'> \
\
</div> \
<!-- DOM and HTML viewers --> \
<textarea name=domview cols=60 rows=12 wrap=off \
onfocus='this.select()' style='display:none;width:100%;height:%halfheight%em;'></textarea><!-- \
--><textarea name=htmlview cols=60 rows=12 wrap=off \
onfocus='this.select()' style='display:none;width:100%;height:%halfheight%em;'></textarea> \
<!-- status line, preview option checkboxes, run/refresh buttons --> \
<table width='100%' style='border:0;padding:0;margin:0'><tr style='border:0;padding:0;margin:0'> \
<td style='border:0;padding:0;margin:0'><!-- \
--><input type=text name=status style='padding:0;width:100%;' \
title='ELAPSED: time (in milliseconds) used to render tiddler content in preview display'><!-- \
--></td><td style='width:1%;border:0;padding:0;margin:0;'><!-- \
--><input type=text name=limit size='6' maxlength='6' style='padding:0;width:5em;text-align:center' \
value='%limit%ms' title='TIME LIMIT: maximum rendering time (in milliseconds) before auto-freezing preview' \
onfocus='this.select()' \
onchange='var val=this.value.replace(/[^0-9]/g,\"\"); if (!val.length) val=this.defaultValue; \
this.value=val+\"ms\"; config.options.txtPreviewAutoFreeze=val; saveOptionCookie(\"txtPreviewAutoFreeze\"); \
this.form.freeze.checked=false; config.macros.preview.render(\"%srcid%\",\"%previd%\",true);'><!-- \
--></td><td style='width:1%;border:0;padding:0;margin:0;'><!-- \
--><input type=text name=height size='4' maxlength='4' style='padding:0;width:4em;text-align:center' \
value='%height%em' title='HEIGHT: size (in \"ems\") of preview area, including controls' \
onfocus='this.select()' \
onchange='var val=this.value.replace(/[^0-9]/g,\"\"); if (!val.length) val=this.defaultValue; \
this.value=val+\"em\"; document.getElementById(\"%previd%\").firstChild.setAttribute(\"height\",val); \
config.macros.preview.render(\"%srcid%\",\"%previd%\",true)'><!-- \
--></td><td style='width:1%;border:0;padding:0;margin:0;text-align:right;white-space:nowrap'> \
<input type=checkbox name=dom style='display:inline;width:auto;margin:1px;' \
title='show Document Object Model (DOM) information' \
onclick='config.macros.preview.renderDOM(\"%previd%\");'>DOM \
<input type=checkbox name=html style='display:inline;width:auto;margin:1px;' \
title='show rendered HTML' \
onclick='config.macros.preview.renderHTML(\"%previd%\");'>HTML \
<input type=checkbox name=freeze style='display:inline;width:auto;margin:1px;' %frozen% \
title='do not update preview display as changes are made' \
onclick='var p=document.getElementById(\"%previd%\"); \
if (this.checked) this.form.status.value+=config.macros.preview.freezeMsg; \
else config.macros.preview.render(\"%srcid%\",\"%previd%\",true);'>freeze \
<input type=button style='display:inline;width:auto;' value='refresh' \
title='update preview display' \
onclick='config.macros.preview.render(\"%srcid%\",\"%previd%\",true)'> \
</td></tr></table> \
</span></form>"
}
//}}}
// // toolbar definition
//{{{
config.commands.previewTiddler = {
text: 'preview',
tooltip: 'show key-by-key preview',
text_alt: '\u221Apreview',
handler: function(event,src,title) {
var here=story.findContainingTiddler(src); if (!here) return;
var elems=here.getElementsByTagName("span");
for (var e=0; e<elems.length; e++) {
if (elems[e].getAttribute("editid")) {
var show=elems[e].style.display=="none";
src.innerHTML=show?this.text_alt:this.text;
elems[e].style.display=show?"block":"none";
config.macros.preview.findContainingForm(elems[e]).freeze.checked=!show;
if (show) config.macros.preview.render(elems[e].getAttribute("editid"),elems[e].id);
}
}
return false;
}
};
//}}}
Type the text for 'New Tiddler'
/***
|Name:|RenameTagsPlugin|
|Description:|Allows you to easily rename or delete tags across multiple tiddlers|
|Version:|3.0 ($Rev: 5501 $)|
|Date:|$Date: 2008-06-10 23:11:55 +1000 (Tue, 10 Jun 2008) $|
|Source:|http://mptw.tiddlyspot.com/#RenameTagsPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
Rename a tag and you will be prompted to rename it in all its tagged tiddlers.
***/
//{{{
config.renameTags = {
prompts: {
rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",
remove: "Remove the tag '%0' from %1 tidder%2?"
},
removeTag: function(tag,tiddlers) {
store.suspendNotifications();
for (var i=0;i<tiddlers.length;i++) {
store.setTiddlerTag(tiddlers[i].title,false,tag);
}
store.resumeNotifications();
store.notifyAll();
},
renameTag: function(oldTag,newTag,tiddlers) {
store.suspendNotifications();
for (var i=0;i<tiddlers.length;i++) {
store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old
store.setTiddlerTag(tiddlers[i].title,true,newTag); // add new
}
store.resumeNotifications();
store.notifyAll();
},
storeMethods: {
saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,
saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
if (title != newTitle) {
var tagged = this.getTaggedTiddlers(title);
if (tagged.length > 0) {
// then we are renaming a tag
if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))
config.renameTags.renameTag(title,newTitle,tagged);
if (!this.tiddlerExists(title) && newBody == "")
// dont create unwanted tiddler
return null;
}
}
return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created);
},
removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,
removeTiddler: function(title) {
var tagged = this.getTaggedTiddlers(title);
if (tagged.length > 0)
if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))
config.renameTags.removeTag(title,tagged);
return this.removeTiddler_orig_renameTags(title);
}
},
init: function() {
merge(TiddlyWiki.prototype,this.storeMethods);
}
}
config.renameTags.init();
//}}}
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options" "Change TiddlyWiki advanced options">>
<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>
for Javascript Find And Run Robot plugins
#mainMenu{
position:static;
width:21em;
border-bottom:1px solid #0045BC;
}
#sidebarOptions{
width:15em;
margin: 0 0 0 4em;
padding-bottom: 1em;
}
#sidebar{
width:25em;
left:0;
border-right:1px solid #0045BC;
}
#displayArea{
margin: 1em 1em 0 25em
}
#sidebarTabs{
width:20em;
border-top:1px solid #0045BC;
padding: 0 0 0 4em;
}
/*{{{*/
* html .tiddler {height:1%;}
body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}
hr {height:1px;}
a {text-decoration:none;}
dt {font-weight:bold;}
ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}
.txtOptionInput {width:11em;}
#contentWrapper .chkOptionInput {border:0;}
.externalLink {text-decoration:underline;}
.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}
.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}
/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
#mainMenu .tiddlyLinkExisting,
#mainMenu .tiddlyLinkNonExisting,
#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}
.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}
#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}
.wizard {padding:0.1em 1em 0em 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}
#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
#messageArea a {text-decoration:underline;}
.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}
.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}
.tabset {padding:1em 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}
#contentWrapper {display:block;}
#splashScreen {display:none;}
#displayArea {margin:1em 17em 0em 14em;}
.toolbar {text-align:right; font-size:.9em;}
.tiddler {padding:1em 1em 0em 1em;}
.missing .viewer,.missing .title {font-style:italic;}
.title {font-size:1.6em; font-weight:bold;}
.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}
.tiddler .button {padding:0.2em 0.4em;}
.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}
.footer {font-size:.9em;}
.footer li {display:inline;}
.annotation {padding:0.5em; margin:0.5em;}
* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}
.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}
.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}
.fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}
.sparkline {line-height:1em;}
.sparktick {outline:0;}
.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}
* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
|''Name:''|IntelliTaggerPlugin|
|''Version:''|1.0.2 (2007-07-25)|
|''Type:''|plugin|
|''Source:''|http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin|
|''Author:''|Udo Borkowski (ub [at] abego-software [dot] de)|
|''Documentation:''|[[IntelliTaggerPlugin Documentation]]|
|''~SourceCode:''|[[IntelliTaggerPlugin SourceCode]]|
|''Licence:''|[[BSD open source license (abego Software)]]|
|''~CoreVersion:''|2.0.8|
|''Browser:''|Firefox 1.5.0.2 or better|
***/
/***
!Version History
* 1.0.2 (2007-07-25):
** Feature: "Return" key may be used to accept first tag suggestion (beside "Alt-1")
** Bugfix: Keyboard shortcuts (Alt+3 etc.) shifted
* 1.0.1 (2007-05-18): Improvement: Speedup when using TiddlyWikis with many tags
* 1.0.0 (2006-04-26): Initial release
***/
/***
!Source Code
***/
//{{{
// Ensure the Plugin is only installed once.
//
if (!version.extensions.IntelliTaggerPlugin) {
// Ensure the global abego namespace is set up.
if (!window.abego) window.abego = {};
if (!abego.internal) abego.internal = {};
// Opens an alert with the given string and throws an exception
// with the same string after the alert is closed.
//
abego.alertAndThrow = function(s) {
alert(s);
throw s;
};
if (version.major < 2) {
abego.alertAndThrow("Use TiddlyWiki 2.0.8 or better to run the IntelliTagger Plugin.");
}
version.extensions.IntelliTaggerPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date(2007, 6, 25),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin",
documentation: "[[IntelliTaggerPlugin Documentation]]",
sourcecode: "[[IntelliTaggerPlugin SourceCode]]",
author: "Udo Borkowski (ub [at] abego-software [dot] de)",
licence: "[[BSD open source license (abego Software)]]",
tiddlywiki: "Version 2.0.8 or better",
browser: "Firefox 1.5.0.2 or better"
};
//}}}
//#startOf: MainCode
//{{{
// ========================================================================
// Utilities ==============================================================
// ========================================================================
// ========================================================================
// Popup
//
// A Popup is an HTML element floating on top of the main HTML page.
//
// The HTML element (typically a "div" element) is added as a direct child
// of the document.body.
//
// A Popup element should respect the following style conventions:
//
// position = "absolute"; // required.
// left = aDimension; // required. E.g. "10px"
// // When not defined the Popup is not displayed.
// top = aDimension; // required. E.g. "10px"
// // When not defined the Popup is not displayed.
// background = aColor; // optional. E.g. "white"
// // When not defined the Popup is transparent.
// border = aBorderSpec; // optional. E.g. "1px solid DarkGray"
// width = aDimension; // optional. E.g. "200px"
// // When not defined the width is calculated
// // automatically.
// height = aDimension; // optional. E.g. "200px"
// // When not defined the height is calculated
// // automatically.
// ========================================================================
abego.createEllipsis = function(place) {
var e = createTiddlyElement(place,"span");
e.innerHTML = "…";
};
// Returns true iff the given element is "opened as a popup",
// i.e. a direct child of the document.body.
//
// @param element [may be null/undefined]
// an HTML element
//
abego.isPopupOpen = function(element) {
return element && element.parentNode == document.body;
};
// Opens the given element as a popup.
//
// @param element
// an HTML element
//
abego.openAsPopup = function(element) {
if (element.parentNode != document.body)
document.body.appendChild(element);
};
// Closes the given popup.
// Does nothing when the element is not a popup or not open.
//
// @param element [may be null/undefined]
// an HTML element
//
abego.closePopup = function(element) {
if (abego.isPopupOpen(element))
document.body.removeChild(element);
};
// Returns the rectangle of the (browser) window
//
// @return {left,top,height,width}
//
abego.getWindowRect = function() {
return {
left: findScrollX(),
top: findScrollY(),
height: findWindowHeight(),
width: findWindowWidth()
};
};
// Moves the given element to the given position (in pixel).
//
abego.moveElement = function(element, left, top) {
element.style.left = left + "px";
element.style.top = top + "px";
};
// Centers the given element on the window.
//
// The element must have absolute position
//
abego.centerOnWindow = function(element) {
if (element.style.position != "absolute")
throw "abego.centerOnWindow: element must have absolute position";
var winRect = abego.getWindowRect();
abego.moveElement(
element,
winRect.left + (winRect.width - element.offsetWidth) / 2,
winRect.top + (winRect.height - element.offsetHeight) / 2);
};
// Returns true if e is either self or a descendant (child, grandchild,...) of self.
//
// @param self DOM:Element
// @param e DOM:Element [may be null]
//
abego.isDescendantOrSelf = function(self, e) {
while (e) {
if (self == e) return true;
e = e.parentNode;
}
return false;
};
// Returns a set containing the items of the array.
//
// It is an object that has a property for every item of the array.
// The name of the property is the "toString" representation of
// the item. The value of the property is "true".
//
// Duplicate items are removed.
//
abego.toSet = function(array) {
var result = {};
for (var i = 0; i < array.length; i++)
result[array[i]] = true;
return result;
};
// Returns an array with all strings from strings that match the filterRE.
//
// @param maxCount [optional] if defined at most maxCount strings are returned.
abego.filterStrings = function(strings, filterRE, maxCount) {
var result =[];
for (var i = 0; i < strings.length && (maxCount === undefined || result.length < maxCount); i++) {
var s = strings[i];
if (s.match(filterRE))
result.push(s);
}
return result;
};
// @param a [may be null/undefined] Object[]
// @param b [may be null/undefined] Object[]
abego.arraysAreEqual = function(a,b) {
if (!a)
return !b;
if (!b)
return false;
var n = a.length;
if (n != b.length)
return false;
for (var i = 0; i < n; i++)
if (a[i] != b[i])
return false;
return true;
};
// Adjusts the element's position to appear below the anchorElement,
// and ensures the element fits into the window.
//
abego.moveBelowAndClip = function(element, anchorElement) {
if (!anchorElement)
return;
// Position the result below the anchor and resize it if necessary.
var anchorLeft = findPosX(anchorElement);
var anchorTop = findPosY(anchorElement);
var anchorHeight = anchorElement.offsetHeight;
var elementLeft = anchorLeft;
var elementTop = anchorTop + anchorHeight;
// Make sure the result is not wider than the window
var winWidth = findWindowWidth();
if (winWidth < element.offsetWidth) {
element.style.width = (winWidth - 100)+"px";
}
// Ensure that the left and right of the result are not
// clipped by the window. Move it to the left or right, if necessary.
var elementWidth = element.offsetWidth;
if(elementLeft + elementWidth > winWidth)
elementLeft = winWidth - elementWidth-30;
if (elementLeft < 0)
elementLeft = 0;
// Do the actual moving
element.style.left = elementLeft + "px";
element.style.top = elementTop + "px";
element.style.display = "block";
};
abego.compareStrings = function(a, b) {
return (a == b) ? 0 : (a < b) ? -1 : 1;
};
// Sorts the given array alphabetically, ignoring the case.
//
abego.sortIgnoreCase = function(arr) {
var result =[];
// To avoid toLowerCase to be called twice for every comparison
// we convert the strings once and sort the lowercase.
// After sorting we replace them with the cased ones.
//
// Benchmarks have shown that this is significantly faster
// than the ad hoc solution, even for small arrays
// (like 5 Strings (10 chars each))
var n = arr.length;
for (var i = 0; i < n; i++) {
var s = arr[i];
result.push([s.toString().toLowerCase(),s]);
}
result.sort(function(a,b) {
return (a[0] == b[0]) ? 0 : (a[0] < b[0]) ? -1 : 1;
});
for (i = 0; i < n; i++)
arr[i] = result[i][1];
};
// Returns the specified field (input or textarea element), otherwise the first edit field it finds
// or null if it found no edit field at all
//
abego.getTiddlerField = function(story,title,field) {
var tiddler = document.getElementById(story.idPrefix + title);
var e = null;
if (tiddler != null) {
var children = tiddler.getElementsByTagName("*");
for (var t=0; t<children.length; t++) {
var c = children[t];
if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea") {
if(!e)
e = c;
if(c.getAttribute("edit") == field)
e = c;
// break; // adding this break would not be 100% compatible to <= TW 2.0.9. when a
}
}
}
return e;
};
abego.setRange = function(element, start, end) {
// adapted from TaskMacroPlugin by LukeBlanshard.
// http://labwiki.sourceforge.net/#CopyrightAndLicense.
if (element.setSelectionRange) { // Mozilla
element.setSelectionRange(start, end);
// Damn mozilla doesn't scroll to visible. Approximate.
var max = 0.0 + element.scrollHeight;
var len = element.textLength;
var top = max*start/len, bot = max*end/len;
element.scrollTop = Math.min(top, (bot+top-element.clientHeight)/2);
} else if (element.createTextRange != undefined) { // IE
var range = element.createTextRange();
range.collapse();
range.moveEnd("character", end);
range.moveStart("character", start);
range.select();
} else // Other? Too bad, just select the whole thing.
element.select();
};
// TiddlerSet: an object with one property per tiddler in the set.
// The name of the property corresponds to the tiddler name,
// the value is "not false" (e.g. true or a non-zero number).
//
// TagMap<X>: an object that maps a tag to an object of type X (access through properties)
//
abego.internal.TagManager = function() {
var tagReferences = null; // TagMap<{count: natural, tiddlers: TiddlerSet}>
var ensureTagsAreLoaded = function() {
if (tagReferences)
return;
tagReferences = {};
store.forEachTiddler(function(title,tiddler) {
for(var i=0; i<tiddler.tags.length; i++) {
var tag = tiddler.tags[i];
var refedBy = tagReferences[tag];
if (!refedBy) {
refedBy = tagReferences[tag] = {count:0, tiddlers: {}};
}
refedBy.tiddlers[tiddler.title] = true;
refedBy.count += 1;
}
});
};
// When any tags are changed reset the TagManager.
//
var oldTiddlyWikiSaveTiddler = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {
var tiddler = this.fetchTiddler(title);
var oldTags = tiddler ? tiddler.tags : [];
var newTags = (typeof tags == "string") ? tags.readBracketedList() : tags;
oldTiddlyWikiSaveTiddler.apply(this, arguments);
if (!abego.arraysAreEqual(oldTags, newTags))
abego.internal.getTagManager().reset();
};
// When a tiddler is removed that had tags reset the TagManager.
//
var oldTiddlyWikiRemoveTiddler = TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler = function(title) {
var tiddler = this.fetchTiddler(title);
var resetTagManager = tiddler && tiddler.tags.length > 0;
oldTiddlyWikiRemoveTiddler.apply(this, arguments);
if (resetTagManager)
abego.internal.getTagManager().reset();
};
// Resets the TagManager, thus ensures that cached tagging
// information is discarded and the most recent tag state is used.
//
this.reset = function () {
tagReferences = null;
};
// Returns a TiddlerSet with all tiddlers that have the given tag,
// or null when the tag is not used in any tiddler.
//
// @return [may be null]
//
this.getTiddlersWithTag = function(tag) {
ensureTagsAreLoaded();
var tagInfo = tagReferences[tag];
return tagInfo ? tagInfo.tiddlers : null;
};
// Returns an array with the names of all tags defined
// plus the (optional) extraTags.
//
// The tags are sorted alphabetically (caseinsensitive).
//
// @params [optional] an array of tags to be added to the list
//
//
this.getAllTags = function(extraTags) {
ensureTagsAreLoaded();
var result =[];
for (var i in tagReferences)
result.push(i);
for (i = 0; extraTags && i < extraTags.length; i++)
result.pushUnique(extraTags[i], true);
abego.sortIgnoreCase(result);
return result;
};
// An array with two items per tag
// result[i][0] : the tag name
// result[i][1] : TiddlerSet, with tiddlers that are tagged with that tag
//
this.getTagInfos = function() {
ensureTagsAreLoaded();
var result = [];
for (var tiddler in tagReferences) {
result.push([tiddler, tagReferences[tiddler]]);
}
return result;
};
var compareTiddlerCountAndTagName = function(a,b) {
var a1 = a[1];
var b1 = b[1];
var d = b[1].count - a[1].count;
return d != 0 ? d : abego.compareStrings(a[0].toLowerCase(), b[0].toLowerCase());
};
this.getSortedTagInfos = function() {
ensureTagsAreLoaded();
var result = this.getTagInfos();
result.sort(compareTiddlerCountAndTagName);
return result;
};
// @return an array of the tags that "partner" the activeTags,
// sorted by the number of conjoint occurances.
//
this.getPartnerRankedTags = function(activeTags) {
var partnerTagCounts = {};
for (var i = 0; i < activeTags.length; i++) {
var tiddlersWithTag = this.getTiddlersWithTag(activeTags[i]);
for (var name in tiddlersWithTag) {
var tiddler = store.getTiddler(name);
// It may happen that a tiddler is "gone" in the meantime
if (!(tiddler instanceof Tiddler))
continue;
for(var j=0; j<tiddler.tags.length; j++) {
var tag = tiddler.tags[j];
var c = partnerTagCounts[tag];
partnerTagCounts[tag] = c ? c+1 : 1;
}
}
}
var currentTagSet = abego.toSet(activeTags);
var result = [];
for (var n in partnerTagCounts) {
if (!currentTagSet[n])
result.push(n);
}
// Sort the tags by their partner tag count, then alphabetically
result.sort(function (a,b) {
var d = partnerTagCounts[b] - partnerTagCounts[a];
return d != 0 ? d : abego.compareStrings(a.toLowerCase(), b.toLowerCase());
});
return result;
};
}; // of abego.internal.TagManager
abego.internal.getTagManager = function() {
if (!abego.internal.gTagManager) abego.internal.gTagManager = new abego.internal.TagManager();
return abego.internal.gTagManager;
};
// ========================================================================
// IntelliTagger ==========================================================
// ========================================================================
(function(){
var PADDING = 2;
var BORDERWIDTH = 1;
var MAX_FAVORITE_TAGS = 30;
var fSuggestionPopup; // DOM:Element
var fAnchorElement; // DOM:Element
var fOnTagSelected; // function(e) {...}
var fSuggestedTags; // [Tag]
var fActiveTagSet; // TagSet
var fFavoriteTags; // array of Tags, [optional]
if (!abego.IntelliTagger) abego.IntelliTagger = {};
var getAnchorElement = function() {
return fAnchorElement;
};
var isCurrentTag = function(tag) {
return fActiveTagSet[tag];
};
var removeLastWord = function(s) {
var i = s.lastIndexOf(" ");
return (i >= 0) ? s.substr(0,i) : "";
};
var lastWordIsFilter = function(inputField) {
var s = inputField.value;
var len = s.length;
return (len > 0 && s[len-1] != ' ');
};
var ensureFieldEndsWithSpace = function(field) {
var s = field.value;
var len = s.length;
if (len > 0 && s[len-1] != ' ') {
field.value += ' ';
}
};
var updateTag = function(tag, inputField, tiddler) {
if (lastWordIsFilter(inputField))
inputField.value = removeLastWord(inputField.value);
story.setTiddlerTag (tiddler.title,tag,0);
ensureFieldEndsWithSpace(inputField);
abego.IntelliTagger.assistTagging(inputField, tiddler);
};
// returns the n-th suggestion, first counting the favorites, then the normal suggestions
//
// @param n zero-based.
// @return [may be null]
var getNthSuggestion = function(n) {
if (fFavoriteTags && fFavoriteTags.length > n)
return fFavoriteTags[n];
return (fSuggestedTags && fSuggestedTags.length > n)
? fSuggestedTags[n]
: null;
};
var useNthSuggestion = function(n, inputField, tiddler) {
var suggestion = getNthSuggestion(n);
if (suggestion)
updateTag(suggestion, inputField, tiddler);
};
var getFilter = function(inputField) {
var pos = inputField.value.lastIndexOf(" ");
var filter = (pos >= 0) ? inputField.value.substr(++pos,inputField.value.length) : inputField.value;
return new RegExp(filter.escapeRegExp(),"i");
};
var countExpectedTags = function(tags, expectedTagsAsProperties) {
var result = 0;
for (var i = 0; i<tags.length;i++)
if (expectedTagsAsProperties[tags[i]])
result++;
return result;
};
// Returns the number tags that have the same count of tiddlers
// as the index-th tagInfo.
//
// The index-th tag is included in the returned number.
//
// @param sortedTagInfo Array of TagInfos, sorted by count of tiddlers.
//
var getNumberOfTagsWithSameCount = function(sortedTagInfos, index, filterRE) {
var result = 1;
var c = sortedTagInfos[index];
for (var i = index+1; i < sortedTagInfos.length; i++)
if (sortedTagInfos[i][1].count == c) {
if (sortedTagInfos[i][0].match(filterRE))
result++;
} else
break;
return result;
};
var getInitialTagSuggestions = function(filterRE, maxCount) {
var tagInfos = abego.internal.getTagManager().getSortedTagInfos();
var result =[];
var lastCount = 0;
for (var i = 0; i < tagInfos.length; i++) {
var c = tagInfos[i][1].count;
// Stop adding tags to the result if not all tags with that count of tiddlers would fit into the result.
if (c != lastCount) {
if (maxCount && (result.length + getNumberOfTagsWithSameCount(tagInfos, i, filterRE) > maxCount))
break;
lastCount = c;
}
// Don't add tags that are only used in one tiddler.
if (c == 1)
break;
var s = tagInfos[i][0];
if (s.match(filterRE))
result.push(s);
}
return result;
};
var getAllFilteredTags = function(filterRE, extraTags) {
return abego.filterStrings(
abego.internal.getTagManager().getAllTags(extraTags),
filterRE);
};
// Refreshes the tagSuggestions window
//
var refreshPopup = function() {
if (!fSuggestionPopup)
return;
// Load the template for the YourSearchResult
var html = store.getTiddlerText("IntelliTaggerMainTemplate");
if (!html)
html = "<b>Tiddler IntelliTaggerMainTemplate not found</b>";
fSuggestionPopup.innerHTML = html;
// Expand the template macros etc.
applyHtmlMacros(fSuggestionPopup,null);
refreshElements(fSuggestionPopup,null);
};
var onTagClicked = function(e) {
if (!e) var e = window.event;
var tag = this.getAttribute("tag");
if (fOnTagSelected)
fOnTagSelected.call(this,tag, e);
return false;
};
var addSeparator = function(place) {
createTiddlyElement(place,"span",null,"tagSeparator", " | ");
};
var appendTags = function(place, tags, suggestionIndex, excludeTags, maxCount) {
if (!tags)
return;
var excludeTagSet = excludeTags ? abego.toSet(excludeTags) : {};
var n = tags.length;
var c = 0;
for (var i = 0; i < n; i++) {
var tag = tags[i];
if (excludeTagSet[tag])
continue;
if (c > 0)
addSeparator(place);
if (maxCount && c >= maxCount) {
abego.createEllipsis(place);
break;
}
c++;
var shortcutText = "";
var placeForButton = place;
if (suggestionIndex < 10) {
// create a wrapping span that ensures the number and the text are not linebreaked.
placeForButton = createTiddlyElement(place,"span",null,"numberedSuggestion");
suggestionIndex++;
var key = suggestionIndex < 10 ? ""+(suggestionIndex) : "0";
createTiddlyElement(placeForButton,"span",null,"suggestionNumber", key+") ");
var fastKeyText = suggestionIndex == 1 ? "Return or " : "";
shortcutText = " (Shortcut: lt-%0)".format([key, fastKeyText]);
}
var shiftClickToolTip = config.views.wikified.tag.tooltip.format([tag]);
var normalClickToolTip = (isCurrentTag(tag) ? "Remove tag '%0'%1" : "Add tag '%0'%1").format([tag,shortcutText]);
var tooltip = "%0; Shift-Click: %1".format([normalClickToolTip, shiftClickToolTip]);
var btn = createTiddlyButton(
placeForButton,
tag,
tooltip,
onTagClicked,
isCurrentTag(tag) ? "currentTag" : null);
btn.setAttribute("tag",tag);
}
};
var scrollVisible = function() {
// Scroll the window to make the fSuggestionPopup page (and the anchorElement) visible.
if (fSuggestionPopup) window.scrollTo(0,ensureVisible(fSuggestionPopup));
if (getAnchorElement()) window.scrollTo(0,ensureVisible(getAnchorElement()));
};
// Close the suggestions window when the user clicks on the document
// (and not into the getAnchorElement or in the suggestions window)
//
var onDocumentClick = function(e) {
if (!e) var e = window.event;
if (!fSuggestionPopup)
return;
var target = resolveTarget(e);
if (target == getAnchorElement()) return;
if (abego.isDescendantOrSelf(fSuggestionPopup, target)) return;
abego.IntelliTagger.close();
};
addEvent(document,"click",onDocumentClick);
// We added a space to the tags edit field. To avoid that the
// tiddler is marked as "changed" just because of that we trim
// the field value
//
var oldGatherSaveFields = Story.prototype.gatherSaveFields;
Story.prototype.gatherSaveFields = function(e,fields) {
oldGatherSaveFields.apply(this, arguments);
var tags = fields.tags;
if (tags)
fields.tags = tags.trim();
};
var focusTagsField = function(title) {
story.focusTiddler(title,"tags");
var tags = abego.getTiddlerField(story, title, "tags");
if (tags) {
var len = tags.value.length;
abego.setRange(tags, len, len);
window.scrollTo(0,ensureVisible(tags));
}
};
// Attach the assistTagging to the "tags" edit field.
//
var oldEditHandler = config.macros.edit.handler;
config.macros.edit.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
oldEditHandler.apply(this, arguments);
var field = params[0];
if((tiddler instanceof Tiddler) && field == "tags") {
// Just added the "edit tags" field.
// Attach it to the "Tag Suggestions" feature.
var inputField = place.lastChild;
inputField.onfocus = function(e) {
abego.IntelliTagger.assistTagging(inputField, tiddler);
setTimeout(
function() {
focusTagsField(tiddler.title);
}, 100);
};
inputField.onkeyup = function(e) {
if (!e) var e = window.event;
if (e.altKey && !e.ctrlKey && !e.metaKey && (e.keyCode >= 48 && e.keyCode <= 57)) {
useNthSuggestion(e.keyCode == 48 ? 9 : e.keyCode-49, inputField, tiddler);
} else if (e.ctrlKey && e.keyCode == 32) {
useNthSuggestion(0, inputField, tiddler);
} if (!e.ctrlKey && (e.keyCode == 13 || e.keyCode == 10)) {
useNthSuggestion(0, inputField, tiddler);
}
setTimeout(
function() {
abego.IntelliTagger.assistTagging(inputField, tiddler);
}, 100);
return false;
};
// ensure that the tags text ends with a space
// (otherwise the last word is used as a filter when the field gets the focus)
ensureFieldEndsWithSpace(inputField);
}
};
var onEditTags = function(e) {
if (!e) var e = window.event;
var target = resolveTarget(e);
var title = target.getAttribute("tiddler");
if (title) {
story.displayTiddler(target,title,"IntelliTaggerEditTagsTemplate", false);
focusTagsField(title);
}
return false;
};
// Add an "[edit]" button to the "tags" field that is displayed with the tiddler in the ViewTemplate.
// Pressing the button allows editing the tags only, with the text still being displayed in wikified form.
//
var oldTagsHandler = config.macros.tags.handler;
config.macros.tags.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
oldTagsHandler.apply(this, arguments);
abego.IntelliTagger.createEditTagsButton(tiddler, createTiddlyElement(place.lastChild,"li"));
};
// close the Suggestion Window when the tiddler is no longer edited
// (i.e. the tag edit inputfield is gone.)
//
// (Note: we must poll this condition since onblur on the input field
// cannot be used since every click into the suggestion window results
// in a lost focus/blur)
//
var closeIfAnchorElementIsHidden = function() {
if (fSuggestionPopup && fAnchorElement && !abego.isDescendantOrSelf(document, fAnchorElement))
abego.IntelliTagger.close();
};
setInterval(closeIfAnchorElementIsHidden, 100);
//----------------------------------------------------------------------------
// The public API
//----------------------------------------------------------------------------
// @param suggestedTags
// array of strings representing the tags to be suggested.
//
// @param activeTags
// array of strings representing the tags currently "active".
//
// @param favoriteTags [optional]
// a subset of the suggested tags that are "favorites".
// I.e. They should be presented first etc.
//
// @param anchorElement [optional]
// when defined the suggestions are displayed "close" to the anchorElement.
// The page is scrolled to make the anchorElement visible.
// When the anchorElement is not defined the suggestions are displayed in the
// center of the window.
//
// @param onTagSelected [optional]
// function(tag, e) to be called when a tag is selected.
//
abego.IntelliTagger.displayTagSuggestions = function(suggestedTags, activeTags, favoriteTags, anchorElement, onTagSelected) {
fSuggestedTags = suggestedTags;
fActiveTagSet = abego.toSet(activeTags);
fFavoriteTags = favoriteTags;
fAnchorElement = anchorElement;
fOnTagSelected = onTagSelected;
if (!fSuggestionPopup) {
fSuggestionPopup = createTiddlyElement(document.body,"div",null,"intelliTaggerSuggestions");
fSuggestionPopup.style.position = "absolute";
}
refreshPopup();
abego.openAsPopup(fSuggestionPopup);
if (getAnchorElement()) {
var w = getAnchorElement().offsetWidth;
if (fSuggestionPopup.offsetWidth < w) {
fSuggestionPopup.style.width = (w-2*(PADDING+BORDERWIDTH)) + "px";
}
abego.moveBelowAndClip(fSuggestionPopup, getAnchorElement());
} else {
abego.centerOnWindow(fSuggestionPopup);
}
scrollVisible();
};
// Shows the Tag Suggestion Popup for the given tiddler, below the specified inputField.
//
abego.IntelliTagger.assistTagging = function(inputField, tiddler) {
var filterRE = getFilter(inputField);
var s = inputField.value;
if (lastWordIsFilter(inputField))
s = removeLastWord(s);
var activeTags = s.readBracketedList();
var favoriteTags = activeTags.length > 0
? abego.filterStrings(abego.internal.getTagManager().getPartnerRankedTags(activeTags), filterRE, MAX_FAVORITE_TAGS)
: getInitialTagSuggestions(filterRE, MAX_FAVORITE_TAGS);
abego.IntelliTagger.displayTagSuggestions(
getAllFilteredTags(filterRE,activeTags),
activeTags,
favoriteTags,
inputField,
function(tag, e) {
if (e.shiftKey) {
onClickTag.call(this,e);
} else
updateTag(tag, inputField, tiddler);
});
};
// Closes the Tag Suggestions Popup
//
abego.IntelliTagger.close = function() {
abego.closePopup(fSuggestionPopup);
fSuggestionPopup = null;
return false;
};
// Creates an TiddlyButton at the given place to edit the tags of the given tiddler.
//
abego.IntelliTagger.createEditTagsButton = function(tiddler, place, text, tooltip, className, id, accessKey) {
if (!text) text = "[edit]";
if (!tooltip) tooltip = "Edit the tags";
if (!className) className = "editTags";
var editButton = createTiddlyButton(place,text,tooltip, onEditTags, className, id, accessKey);
editButton.setAttribute("tiddler", (tiddler instanceof Tiddler) ? tiddler.title : String(tiddler));
return editButton;
};
abego.IntelliTagger.getSuggestionTagsMaxCount = function() {
return 100;
};
//----------------------------------------------------------------------------
// Macros
//----------------------------------------------------------------------------
// ====Macro intelliTagger ================================================
config.macros.intelliTagger = {
// Standard Properties
label: "intelliTagger",
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var namesAndValues = paramString.parseParams("list",null, true);
var actions = namesAndValues[0]["action"];
for (var i = 0; actions && i < actions.length; i++) {
var actionName = actions[i];
var action = config.macros.intelliTagger.subhandlers[actionName];
if (!action)
abego.alertAndThrow("Unsupported action '%0'".format([actionName]));
action(place,macroName,params,wikifier,paramString,tiddler);
}
},
subhandlers: {
showTags : function(place,macroName,params,wikifier,paramString,tiddler) {
appendTags(place, fSuggestedTags, fFavoriteTags ? fFavoriteTags.length : 0, fFavoriteTags,abego.IntelliTagger.getSuggestionTagsMaxCount());
},
showFavorites : function(place,macroName,params,wikifier,paramString,tiddler) {
appendTags(place, fFavoriteTags, 0);
},
closeButton : function(place,macroName,params,wikifier,paramString,tiddler) {
var button = createTiddlyButton(place, "close", "Close the suggestions", abego.IntelliTagger.close);
},
version : function(place) {
var t = "IntelliTagger %0.%1.%2".format(
[version.extensions.IntelliTaggerPlugin.major,
version.extensions.IntelliTaggerPlugin.minor,
version.extensions.IntelliTaggerPlugin.revision]);
var e = createTiddlyElement(place, "a");
e.setAttribute("href", "http://tiddlywiki.abego-software.de/#IntelliTaggerPlugin");
e.innerHTML = '<font color="black" face="Arial, Helvetica, sans-serif">'+t+'<font>';
},
copyright : function(place) {
var e = createTiddlyElement(place, "a");
e.setAttribute("href", "http://tiddlywiki.abego-software.de");
e.innerHTML = '<font color="black" face="Arial, Helvetica, sans-serif">© 2006-2007 <b><font color="red">abego</font></b> Software<font>';
}
}
};
})();
//}}}
//#endOf: MainCode
//{{{
config.shadowTiddlers["IntelliTaggerStyleSheet"] =
"/***\n"+
"!~IntelliTagger Stylesheet\n"+
"***/\n"+
"/*{{{*/\n"+
".intelliTaggerSuggestions {\n"+
"\tposition: absolute;\n"+
"\twidth: 600px;\n"+
"\n"+
"\tpadding: 2px;\n"+
"\tlist-style: none;\n"+
"\tmargin: 0;\n"+
"\n"+
"\tbackground: #eeeeee;\n"+
"\tborder: 1px solid DarkGray;\n"+
"}\n"+
"\n"+
".intelliTaggerSuggestions .currentTag {\n"+
"\tfont-weight: bold;\n"+
"}\n"+
"\n"+
".intelliTaggerSuggestions .suggestionNumber {\n"+
"\tcolor: #808080;\n"+
"}\n"+
"\n"+
".intelliTaggerSuggestions .numberedSuggestion{\n"+
"\twhite-space: nowrap;\n"+
"}\n"+
"\n"+
".intelliTaggerSuggestions .intelliTaggerFooter {\n"+
"\tmargin-top: 4px;\n"+
"\tborder-top-width: thin;\n"+
"\tborder-top-style: solid;\n"+
"\tborder-top-color: #999999;\n"+
"}\n"+
".intelliTaggerSuggestions .favorites {\n"+
"\tborder-bottom-width: thin;\n"+
"\tborder-bottom-style: solid;\n"+
"\tborder-bottom-color: #999999;\n"+
"\tpadding-bottom: 2px;\n"+
"}\n"+
"\n"+
".intelliTaggerSuggestions .normalTags {\n"+
"\tpadding-top: 2px;\n"+
"}\n"+
"\n"+
".intelliTaggerSuggestions .intelliTaggerFooter .button {\n"+
"\tfont-size: 10px;\n"+
"\n"+
"\tpadding-left: 0.3em;\n"+
"\tpadding-right: 0.3em;\n"+
"}\n"+
"\n"+
"/*}}}*/\n";
config.shadowTiddlers["IntelliTaggerMainTemplate"] =
"<!--\n"+
"{{{\n"+
"-->\n"+
"<div class=\"favorites\" macro=\"intelliTagger action: showFavorites\"></div>\n"+
"<div class=\"normalTags\" macro=\"intelliTagger action: showTags\"></div>\n"+
"<!-- The Footer (with the Navigation) ============================================ -->\n"+
"<table class=\"intelliTaggerFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n"+
" <tr>\n"+
"\t<td align=\"left\">\n"+
"\t\t<span macro=\"intelliTagger action: closeButton\"></span>\n"+
"\t</td>\n"+
"\t<td align=\"right\">\n"+
"\t\t<span macro=\"intelliTagger action: version\"></span>, <span macro=\"intelliTagger action: copyright \"></span>\n"+
"\t</td>\n"+
" </tr>\n"+
"</tbody></table>\n"+
"<!--\n"+
"}}}\n"+
"-->\n";
config.shadowTiddlers["IntelliTaggerEditTagsTemplate"] =
"<!--\n"+
"{{{\n"+
"-->\n"+
"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+
"<div class='title' macro='view title'></div>\n"+
"<div class='tagged' macro='tags'></div>\n"+
"<div class='viewer' macro='view text wikified'></div>\n"+
"<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler'></div>\n"+
"<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>\n"+
"<!--\n"+
"}}}\n"+
"-->\n";
config.shadowTiddlers["BSD open source license (abego Software)"] = "See [[Licence|http://tiddlywiki.abego-software.de/#[[BSD open source license]]]].";
config.shadowTiddlers["IntelliTaggerPlugin Documentation"] = "[[Documentation on abego Software website|http://tiddlywiki.abego-software.de/doc/IntelliTagger.pdf]].";
config.shadowTiddlers["IntelliTaggerPlugin SourceCode"] = "[[Plugin source code on abego Software website|http://tiddlywiki.abego-software.de/archive/IntelliTaggerPlugin/Plugin-IntelliTagger-src.1.0.2.js]]\n";
//}}}
//{{{
(function() {
var oldRestart = restart;
restart = function() {
setStylesheet(store.getTiddlerText('IntelliTaggerStyleSheet'),'IntelliTaggerStyleSheet');
oldRestart.apply(this,arguments);
}
})();
//}}}
//{{{
} // of single install
//}}}
/***
|''Name:''|DeliciousTaggingPlugin|
|''Version:''|0.1|
|''Source''|http://jackparke.googlepages.com/jtw.html#DeliciousTaggingPlugin ([[del.icio.us|http://del.icio.us/post?url=http://jackparke.googlepages.com/jtw.htmlÞliciousTaggingPlugin]])|
|''Author:''|[[Jack]]|
!Description
Allows easy 'del.icio.us'-like tagging in the EditTemplate by showing all tags as a list of link-buttons.
!Usage
Replace your the editorFooter div in your [[EditTemplate]] with the following:
{{{
<div class='editorFooter' macro='deliciousTagging'></div>
}}}
!Code
***/
//{{{
version.extensions.deliciousTagging = {major: 0, minor: 1, revision: 0, date: new Date("June 11, 2007")};
config.macros.deliciousTagging= {};
config.macros.deliciousTagging.onTagClick = function(e)
{
if(!e) var e = window.event;
var tag = this.getAttribute("tag");
var title = this.getAttribute("tiddler");
if(!readOnly)
story.setTiddlerTag(title,tag,0);
return false;
};
config.macros.deliciousTagging.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
if(tiddler instanceof Tiddler) {
var title = tiddler.title;
if(!e) var e = window.event;
var tags = store.getTags();
var lingo = config.views.editor.tagChooser;
for(var t=0; t<tags.length; t++) {
var theTag = createTiddlyButton(place,tags[t][0],lingo.tagTooltip.format([tags[t][0]]),config.macros.deliciousTagging.onTagClick);
theTag.setAttribute("tag",tags[t][0]);
theTag.setAttribute("tiddler",tiddler.title);
place.appendChild(document.createTextNode(" "));
}
}
};
//}}}
/***
''Plugin:'' Tag Cloud Macro
''Author:'' Clint Checketts
''Source URL:''
!Usage
<<tagCloud>>
!Code
***/
//{{{
version.extensions.tagCloud = {major: 1, minor: 0 , revision: 0, date: new Date(2006,2,04)};
//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman
config.macros.tagCloud = {
noTags: "No tag cloud created because there are no tags.",
tooltip: "%1 tiddlers tagged with '%0'"
};
config.macros.tagCloud.handler = function(place,macroName,params) {
var tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);
var tags = store.getTags();
for (var t=0; t<tags.length; t++) {
for (var p=0;p<params.length; p++) if (tags[t][0] == params[p]) tags[t][0] = "";
}
if(tags.length == 0)
createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);
//Findout the maximum number of tags
var mostTags = 0;
for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){
if (tags[t][1] > mostTags) mostTags = tags[t][1];
}
//divide the mostTags into 4 segments for the 4 different tagCloud sizes
var tagSegment = mostTags / 4;
for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){
var tagCloudElement = createTiddlyElement(tagCloudWrapper,"span",null,null,null);
tagCloudWrapper.appendChild(document.createTextNode(" "));
var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip.format(tags[t]),onClickTag,"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));
theTag.setAttribute("tag",tags[t][0]);
}
};
setStylesheet(".tagCloud span{height: 1.8em;margin: 3px;}.tagCloud1{font-size: 1.2em;}.tagCloud2{font-size: 1.4em;}.tagCloud3{font-size: 1.6em;}.tagCloud4{font-size: 1.8em;}.tagCloud5{font-size: 1.8em;font-weight: bold;}","tagCloudsStyles");
//}}}
/***
|''Name:''|TagsTreePlugin|
|''Description:''|Displays tags hierachy as a tree of tagged tiddlers.<br>Can be used to create dynamic outline navigation.|
|''Version:''|1.0.1|
|''Date:''|Jan 04,2008|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0|
!Demo
On the plugin [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] :
*Try to tag some <<newTiddler>> with a tag displayed in the menu and edit MainMenu.
*Look at some tags like [[Plugins]] or [[menu]].
!Installation
#import the plugin,
#save and reload,
#optionally, edit TagsTreeStyleSheet.
! Usage
{{{<<tagsTree>>}}} macro accepts the following //optional// parameters.
|!#|!parameter|!description|!by default|
|1|{{{root}}}|Uses {{{root}}} tag as tree root|- In a //tiddler// content or template : uses the tiddler as root tag.<br>- In the //page// content or template (by ex MainMenu) : displays all untagged tags.|
|2|{{{excludeTag}}}|Excludes all such tagged tiddlers from the tree|Uses default excludeLists tag|
|3|{{{level}}}|Expands nodes until level {{{level}}}.<br>Value {{{0}}} hides expand/collapse buttons.|Nodes are collapsed on first level|
|4|{{{depth}}}|Hierachy depth|6 levels depth (H1 to H6 header styles)|
|5|{{{sortField}}}|Alternate sort field. By example : "index".|Sorts tags and tiddlers alphabetically (on their title)|
|6|{{{labelField}}}|Alertnate label field. By example : "label".|Displays tiddler's title|
!Useful addons
*[[FieldsEditorPlugin]] : //create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.
*[[TaggerPlugin]] : Provides a drop down listing current tiddler tags, and allowing toggling of tags.
!Advanced Users
You can change the global defaults for TagsTreePlugin, like default {{{level}}} value or level styles, by editing or overriding the first config.macros.tagsTree attributes below.
!Code
***/
//{{{
config.macros.tagsTree = {
expand : "+",
collapse : "--",
depth : 6,
level : 1,
sortField : "",
labelField : "",
styles : ["h1","h2","h3","h4","h5","h6"],
trees : {}
}
config.macros.tagsTree.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
var root = params[0] ? params[0] : (tiddler ? tiddler.title : null);
var excludeTag = params[1] ? params[1] : "excludeTagsTree";
var level = params[2] ? params[2] : config.macros.tagsTree.level;
var depth = params[3] ? params[3] : config.macros.tagsTree.depth;
var sortField = params[4] ? params[4] : config.macros.tagsTree.sortField;
var labelField = params[5] ? params[5] : config.macros.tagsTree.labelField;
var showButtons = (level>0);
var id = config.macros.tagsTree.getId(place);
if (config.macros.tagsTree.trees[id]==undefined) config.macros.tagsTree.trees[id]={};
config.macros.tagsTree.createSubTree(place,id,root,excludeTag,[],level>0 ? level : 1,depth, sortField, labelField,showButtons);
}
config.macros.tagsTree.createSubTree = function(place, id, root, excludeTag, ancestors, level, depth, sortField, labelField,showButtons){
var childNodes = root ? this.getChildNodes(root, ancestors) : this.getRootTags(excludeTag);
var isOpen = (level>0) || (!showButtons);
if (root && this.trees[id][root]!=undefined) isOpen = this.trees[id][root];
if (root && ancestors.length) {
var t = store.getTiddler(root);
if (childNodes.length && depth>0) {
var wrapper = createTiddlyElement(place , this.styles[Math.min(Math.max(ancestors.length,1),6)-1],null,"branch");
if (showButtons) {
b = createTiddlyButton(wrapper, isOpen ? config.macros.tagsTree.collapse : config.macros.tagsTree.expand, null, config.macros.tagsTree.onClick);
b.setAttribute("treeId",id);
b.setAttribute("tiddler",root);
}
createTiddlyText(createTiddlyLink(wrapper, root),t&&labelField ? t.fields[labelField] ? t.fields[labelField] : root : root);
}
else
createTiddlyText(createTiddlyLink(place, root,false,"leaf"),t&&labelField ? t.fields[labelField] ? t.fields[labelField] : root : root);
}
if (childNodes.length && depth) {
var d = createTiddlyElement(place,"div",null,"subtree");
d.style.display= isOpen ? "block" : "none";
if (sortField)
childNodes.sort(function(a, b){
var fa=a.fields[sortField];
var fb=b.fields[sortField];
return (fa==undefined && fb==undefined) ? a.title < b.title ? -1 : a.title > b.title ? 1 : 0 : (fa==undefined && fb!=undefined) ? 1 :(fa!=undefined && fb==undefined) ? -1 : fa < fb ? -1 : fa > fb ? 1 : 0;
})
for (var cpt=0; cpt<childNodes.length; cpt++)
this.createSubTree(d, id, childNodes[cpt].title, excludeTag, ancestors.concat(root), level-1, depth-1, sortField, labelField, showButtons);
}
}
config.macros.tagsTree.onClick = function(e){
var id = this.getAttribute("treeId");
var tiddler = this.getAttribute("tiddler");
var n = this.parentNode.nextSibling;
var isOpen = n.style.display != "none";
if(config.options.chkAnimate && anim && typeof Slider == "function")
anim.startAnimating(new Slider(n,!isOpen,null,"none"));
else
n.style.display = isOpen ? "none" : "block";
this.firstChild.nodeValue = isOpen ? config.macros.tagsTree.expand : config.macros.tagsTree.collapse;
config.macros.tagsTree.trees[id][tiddler]=!isOpen;
return false;
}
config.macros.tagsTree.getChildNodes = function(root ,ancestors){
var childs = store.getTaggedTiddlers(root);
var result = new Array();
for (var cpt=0; cpt<childs.length; cpt++)
if (childs[cpt].title!=root && ancestors.indexOf(childs[cpt].title)==-1) result.push(childs[cpt]);
return result;
}
config.macros.tagsTree.getRootTags = function(excludeTag){
var tags = store.getTags(excludeTag);
tags.sort(function(a,b) {return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : (a[0].toLowerCase() == b[0].toLowerCase() ? 0 : +1);});
var result = new Array();
for (var cpt=0; cpt<tags.length; cpt++) {
var t = store.getTiddler(tags[cpt][0]);
if (!t || t.tags.length==0) result.push(t ? t : {title:tags[cpt][0],fields:{}});
}
return result;
}
config.macros.tagsTree.getId = function(element){
while (!element.id && element.parentNode) element=element.parentNode;
return element.id ? element.id : "<html>";
}
config.shadowTiddlers.TagsTreeStyleSheet = "/*{{{*/\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".leaf, .subtree {display:block; margin-left : 0.5em}\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".subtree {margin-bottom:0.5em; overflow: hidden;}\n";
config.shadowTiddlers.TagsTreeStyleSheet +="#mainMenu {text-align:left}\n";
config.shadowTiddlers.TagsTreeStyleSheet +=".branch .button {border:1px solid #DDD; color:#AAA;font-size:9px;padding:0 2px;margin-right:0.3em;vertical-align:middle;text-align:center;}\n";
config.shadowTiddlers.TagsTreeStyleSheet +="/*}}}*/";
store.addNotification("TagsTreeStyleSheet", refreshStyles);
config.shadowTiddlers.MainMenu="<<tagsTree>>"
config.shadowTiddlers.PageTemplate = config.shadowTiddlers.PageTemplate.replace(/id='mainMenu' refresh='content' /,"id='mainMenu' refresh='content' force='true' ")
//}}}
Type the text for 'New Tiddler'
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler' fds aaa
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
To be written by mouser from farr help.
Filling out stuff now.
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'