Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
/***\n!Metadata:\n|''Name:''|ArchivedTimeline|\n|''Description:''|Timeline archived monthly.|\n|''Version:''|0.7.0|\n|''Date:''|Aug 25, 2007|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|\n|''~CoreVersion:''|2.0.11|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n\n!Syntax:\n{{{<<timeline [modified|created [maxentries [dateFormate]]]>>}}}\n!Examples:\n{{{<<timeline>>}}}\n{{{<<timeline created 10>>}}}\n{{{<<timeline modified 10 "MMM DD, YYYY">>}}}\n\n!Revision History:\n|''Version''|''Date''|''Note''|\n|0.7.0|Jul 25, 2006|Accept a date format parameter|\n|0.6.3|Jan 14, 2007|Cleaned codes, Removed config.macros.timeline.slider and config.macros.timeline.onClickSlider|\n|0.6.2|Dec 10, 2006|Add monthFormat to display month format for Chinese|\n|0.6.1|Aug 12, 2006|A great effect on config.macros.timeline.slider for Firefox, thanks Bob McElrath|\n|0.6.0|Jul 25, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|\n|0.5.2|Jun 21, 2006|Fixed bugs for dateFormat of TW 2.1|\n|~|~|Change default dateFormat to "0DD MMM, YYYY"|\n|0.5.1|Jun 04, 2006|Added config.macros.archivedTimeline.orderBy for localization|\n|0.5.0|Apr 19, 2006|Fixed bug for twice records of the same date ()|\n|~|~|Added Date.prototype.convertToLocalYYYYMMDDHHMM<<br>>in order to backward compatible with 2.0.6-|\n|0.4.0|Apr 03, 2006|Added new parameter, {{{<<timeline [sortfield] [maxentries]>>}}}|\n|~|~|Added config.options.txtTimelineMaxentries|\n|0.3.1|Feb 04, 2006|JSLint checked|\n|0.3.0|Feb 04, 2006|Fixed several missing variable declarations|\n|0.2.0|Dec 26, 2005|changed for the new feature of Macro timeline of TW 2.0.0 beta 6|\n|0.1.0|Nov 3, 2005|Initial release|\n\n!Code section:\n***/\n//{{{\nversion.extensions.archivedTimeline = {major: 0, minor: 7, revision: 0,\n date: new Date("Aug 26, 2007"),\n name: "ArchivedTimeline",\n type: "Macro",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\nconfig.options.txtTimelineMaxentries=0;\nconfig.macros.archivedTimeline = {\n tooltips: "Archives sorted by ",\n orderBy:{modified: "modified", created: "created"},\n monthFormat: "0DD MMM YYYY",\n dateFormat: "0DD MMM YYYY"\n};\nconfig.macros.timeline = config.macros.archivedTimeline;\n\nconfig.macros.timeline.handler = function(place,macroName,params) {\n var field = params[0] ? params[0] : "modified";\n\n place.appendChild(document.createTextNode(this.tooltips + this.orderBy[field]));\n var tiddlers = store.reverseLookup("tags","excludeLists",false,field);\n var lastMonth = ""; var lastDay = ""; var theText = "----\sn"; var i = 0;\n var last = (params[1])?params[1]:config.options.txtTimelineMaxentries;\n last = (isNaN(last)||last<1) ? 0:tiddlers.length-Math.min(tiddlers.length,parseInt(last));\n var dateFormat = params[2] ? params[2] : this.dateFormat;\n var cookie; var archives;\n for (var t=tiddlers.length-1; t>=last; t--) {\n var tiddler = tiddlers[t];\n var theMonth = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,6);\n var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);\n if(theMonth != lastMonth) {\n if (lastMonth === "") {\n lastMonth = theMonth;\n }\n else {\n place.appendChild(document.createElement('hr'));\n cookie = 'chktimeline'+(i++);\n archives = this.formatString(this.monthFormat, lastMonth);\n var panel = config.macros.slider.createSlider(place,cookie,archives,this.tooltips + archives);\n wikify(theText,panel);\n lastMonth = theMonth; theText = '----\sn';\n }\n }\n if(theDay != lastDay){\n theText += tiddler[field].formatString(dateFormat) + '\sn';\n lastDay = theDay; \n }\n theText += '* [[' + tiddler.title + ']]\sn';\n }\n place.appendChild(document.createElement('hr'));\n cookie = 'chktimeline'+(i++);\n archives = this.formatString(this.monthFormat, lastMonth);\n var panel = config.macros.slider.createSlider(place,cookie,archives,this.tooltips + archives);\n wikify(theText,panel);\n place.appendChild(document.createElement('hr'));\n};\n\nconfig.macros.timeline.formatString = function(template, yyyymm)\n{\n var dateString = new Date(yyyymm.substr(0,4)+'/'+yyyymm.substr(4,2)+'/01');\n template = template.replace(/DDD|0DD|DD/g,'');\n return dateString.formatString(template);\n};\nif (!Date.prototype.convertToLocalYYYYMMDDHHMM){\n Date.prototype.convertToLocalYYYYMMDDHHMM = function(){\n return(String.zeroPad(this.getFullYear(),4) + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2));\n }\n}\n//}}}\n
/***\n|''Name:''|CommentPlugin|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|Tim Morgan (modified by Bram Chen|\n|''Version:''|1.0.0|\n|''Date:''|Aug 25, 2007|\n|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|\n|''~CoreVersion:''|2.0.11|\n|''Description:''|Adds "comments" to any TiddlyWiki or adaptation.|\n|~|Used in conjunction with the RecentPlugin, one can have a decent forum environment.|\n\n''Translation sample 1:''\n{{{\nconfig.CommentPlugin.CPlingo = {\n dateFormat: "YYYY年0MM月0DD日 0hh:0mm:0ss",\n CommentInTitle: " 迴響 ",\n comments:"迴響",\n add:"回應 »",\n edit:"編輯",\n tooltips:"發表關於此文的相關意見",\n Title: "%0 迴響 %1",\n CommenteditTemplate: {yourName: "請簽名:", nickName: "(中英文暱稱)", comments: "留言內容:"}\n};\n}}}\n''Translation sample 2:''\n{{{\nconfig.CommentPlugin = {\n CPlingo:{\n dateFormat: "DD MMM YYYY 0hh:0mm:0ss",\n CommentInTitle: " Comment ",\n comments: "comments",\n add: "New Comment Here...",\n edit: "Edit",\n tooltips:" Create a new comment tiddler associated with this tiddler",\n Title: "%0 Comment %1",\n CommenteditTemplate: {yourName: "Your Name: ", nickName: "(nick name)", comments: "Comment: "}\n };\n}}}\n\n''Revision history:''\n* v1.0.0\n** Fixed bug, those tiddlers tagging with some other tiddlers and not tagged with only_on_tags would also be created a comment links with count 0.\n* v0.8.0 (Jan 17, 2007)\n** Some minor changes and bugs fixed (Bram)\n* v0.7.0 (Nov 09, 2006)\n** Minor changes, more easier to be translated (Bram)\n* v0.6.0 (Nov 09, 2006)\n** Runs compatibly with TW 2.1.0+ (Bram)\n* v0.5.0 (Jun 15, 2006)\n** Fixed bug for feature of CommentEditTemplate (bug reported by MilchFlasche, fixed by Bram)\n** Fixed bug in redefined TiddlyWiki.prototype.saveTiddler (Bram)\n* v0.4.0 (Jun 03, 2006) Added CommentEditTemplate (Bram)\n* v0.3.0 (Jun 01, 2006) Some minor changes for readOnly mode (Bram)\n* v0.2.0 (Apr 04, 2006) Fixed bug for only_on_tags (Bram)\n* v0.1.0 (Mar 13, 2006) Modified by Bram Chen.\n***/\n// //''Code section:''\n//{{{\nconfig.CommentPlugin = {\n CPlingo:{\n dateFormat: "DD MMM YYYY 0hh:0mm:0ss",\n CommentInTitle: " Comment ",\n comments: "comments",\n add: "New Comment Here...",\n edit: "Edit",\n tooltips: "Create a new comment tiddler associated with this tiddler",\n Title: "%0 Comment %1",\n CommenteditTemplate: {yourName: "Your Name: ", nickName: "(nick name)", comments: "Comment: "}\n },\n only_on_tags: ['Public'],\n not_on_tags: ['about'],\n // "true" or "false"...\n fold_comments: true,\n default_fold: true,\n max_comment_count: 500\n};\n\nvar CPlingo = config.CommentPlugin.CPlingo;\nconfig.CommentPlugin.only_on_tags.push(CPlingo.comments);\n\nfunction get_parent(tiddler){\n while(tiddler.isTagged(CPlingo.comments)){\n tiddler=store.fetchTiddler(tiddler.tags[0]);\n }\n return tiddler\n};\n\nfunction count_comments(title){\n var tagged=store.getTaggedTiddlers(title);\n var count=0;\n for(var i=0;i<tagged.length;i++){\n if(tagged[i].tags.contains(CPlingo.comments)){\n count+=count_comments(tagged[i].title)+1;\n }\n }\n return count\n};\nconfig.shadowTiddlers.ViewTemplate += "\sn<div class='comments' macro='comments'></div>";\n\nconfig.shadowTiddlers.CommentEditTemplate="<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler wikibar'></div><div class='title' macro='view title'></div><div class='editor' macro='edit tags' style='display:none;'></div><div class='GuestSign' >" + CPlingo.CommenteditTemplate.yourName + "<span macro='option txtUserName'></span>" + CPlingo.CommenteditTemplate.nickName + "<br />" + CPlingo.CommenteditTemplate.comments + "</div><div class='editor' macro='edit text'></div>";\nconfig.tiddlerTemplates[3]="CommentEditTemplate"; \nvar COMMENT_EDIT_TEMPLATE = 3;\n\nconfig.shadowTiddlers.CommentPluginStyle = '\sn/*{{{*/\sn.commentTags ul {list-style:none; padding-left:0px; margin: 0 0 3px 0;}\sn.commentTags li {display:inline; color:#999;}\sn.commentTags li a.button {color:#999;}\sn.comment {border-left:1px solid #ccc; margin-top:10px; margin-left:10px; padding:5px;}\sn.newCommentLink {padding-top:10px}\sn.tagging, .selected .tagging, .tiddler .tagging {display:none;}\sn.comment a.button {padding:0px; font-size:smaller; background-color:lightgray;}\sn.comments a.button {background-color:lightgray;}\sn/*}}}*/';\nconfig.shadowTiddlers.StyleSheet += '\sn[[CommentPluginStyle]]';\nconfig.macros.newCommentLink = {\n label: CPlingo.add,\n prompt: CPlingo.tooltips,\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n if(tiddler && store.tiddlerExists(tiddler.title) && !readOnly && (!window.zw || zw.loggedIn || zw.anonEdit)) {\n if(tiddler.tags.containsAny(config.CommentPlugin.not_on_tags) || !tiddler.tags.containsAny(config.CommentPlugin.only_on_tags))\n return;\n var onclick = function(e) {\n var e = (e)?e:window.event;\n var theTarget = resolveTarget(e);\n var tagxs = tiddler.title.split(CPlingo.CommentInTitle);\n var title = (tiddler.title.indexOf(CPlingo.CommentInTitle)!=-1)? tagxs[0] : tiddler.title;\n title = CPlingo.Title.format([title,(new Date()).formatString(CPlingo.dateFormat)]);\n var comment = store.createTiddler(title);\n comment.text = '';\n comment.tags = [tiddler.title, CPlingo.comments,'excludeLists'];\n readOnly = false;\n story.displayTiddler(theTarget, title, COMMENT_EDIT_TEMPLATE);\n readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;\n story.focusTiddler(title,"text");\n return false;\n }\n createTiddlyButton(place, this.label, this.prompt, onclick);\n }\n }\n};\nconfig.macros.comments = {\n dateFormat: CPlingo.dateFormat,\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n if(tiddler.title==CPlingo.comments) return;\n var comments = store.getTaggedTiddlers(tiddler.title, 'created');\n var count = count_comments(tiddler.title);\n if(count>0 && !tiddler.tags.contains(CPlingo.comments) && config.CommentPlugin.fold_comments) {\n var show = createTiddlyElement(place, 'p');\n show.innerHTML = '<a href="#" onclick="var e=document.getElementById(\s'comments'+tiddler.title+'\s');e.style.display=e.style.display==\s'block\s'?\s'none\s':\s'block\s';return false;">' + CPlingo.comments +'('+count+') »</a>';\n }\n var place = createTiddlyElement(place, 'div', 'comments'+tiddler.title, 'comments');\n if(count>0 && !tiddler.tags.contains(CPlingo.comments) && config.CommentPlugin.fold_comments && config.CommentPlugin.default_fold)\n place.style.display = 'none';\n else\n place.style.display = 'block';\n for(var i=0; i<comments.length; i++) {\n if(!comments[i].tags.contains(CPlingo.comments))continue;\n var container = createTiddlyElement(place, 'div', null, 'comment');\n var title = createTiddlyElement(container, 'strong');\n var link = createTiddlyLink(title, comments[i].modifier, true);\n createTiddlyElement(title, 'span', null, null, ', '+comments[i].created.formatString(this.dateFormat));\n/* ## remove editable option for security concern\n if(comments[i].modifier == config.options.txtUserName) {\n createTiddlyElement(title, 'span', null, null, ' (');\n var edit = createTiddlyLink(title, comments[i].title);\n edit.innerHTML = CPlingo.edit;\n createTiddlyElement(title, 'span', null, null, ')');\n }\n*/\n wikify('\sn'+comments[i].text+'\sn',container);\n config.macros.comments.handler(container,null,null,null,null,comments[i]);\n }\n readOnly = false;\n config.macros.newCommentLink.handler(place,null,null,null,null,tiddler);\n// wikify('<'+'<newCommentLink>>',place);\n readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;\n }\n};\nvar CPCloseTiddlers = [];\nTiddlyWiki.prototype.CommentPlugin_saveTiddler = TiddlyWiki.prototype.saveTiddler;\nTiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {\n tags=(!window.zw && typeof tags == "string") ? tags.readBracketedList() : tags;\n if(tags.contains(CPlingo.comments)){\n newBody=newBody.htmlDecode(); // comment this line, for working with HTMLAreaPackage\n newBody=newBody.substr(0,config.CommentPlugin.max_comment_count);\n newBody=newBody.htmlEncode(); // comment this line, for working with HTMLAreaPackage\n }\n var t = this.CommentPlugin_saveTiddler(title,newTitle,newBody,modifier,modified,tags);\n if(tags.contains(CPlingo.comments)) {\n var original = config.CommentPlugin.default_fold;\n config.CommentPlugin.default_fold = false;\n// story.refreshTiddler(get_parent(t).title, DEFAULT_VIEW_TEMPLATE, true);\n story.refreshTiddler(t.tags[0].split(CPlingo.CommentInTitle)[0], DEFAULT_VIEW_TEMPLATE, true);\n config.CommentPlugin.default_fold = original;\n CPCloseTiddlers.push(newTitle);\n setTimeout("story.closeTiddler(CPCloseTiddlers.pop(), true)", 500);\n }\n return t;\n};\nStory.prototype.chooseTemplateForTiddler = function(title,template)\n{\n if(!template)\n template = DEFAULT_VIEW_TEMPLATE;\n if(template == DEFAULT_VIEW_TEMPLATE\n || template == DEFAULT_EDIT_TEMPLATE\n || template == COMMENT_EDIT_TEMPLATE)\n template = config.tiddlerTemplates[template];\n return template;\n};\n//}}}
/***\n|''Name:''|CommentTabPlugin|\n|''Source:''|[[TiddlyWiki-zh|http://tiddlywiki-zh.googlecode.com/svn/trunk/contributors/BramChen/locales/plugins/]]|\n|''Requires:''|[[CommentPlugin|http://sourceforge.net/project/showfiles.php?group_id=150646]]|\n|''Descriptions:''|Breaks the Timeline tab into "Tiddlers" and "Comments".|\n***/\n//{{{\nfunction in_array(item, arr){for(var i=0;i<arr.length;i++)if(item==arr[i])return true};\nfunction get_parent(tiddler){while(tiddler && in_array(config.CommentPlugin.CPlingo.comments, tiddler.tags)) tiddler=store.fetchTiddler(tiddler.tags[0]);return tiddler};\nconfig.options.txtTimelineTab = 'timelineTab'; // huh?\nconfig.shadowTiddlers.TabTimelineTiddlers = config.shadowTiddlers.TabTimeline;\nconfig.shadowTiddlers.TabTimeline = "<<tabs txtTimelineTab Tiddlers Tiddlers TabTimelineTiddlers "+ config.CommentPlugin.CPlingo.comments + config.CommentPlugin.CPlingo.CommentInTitle + " TabTimelineComments>>";\nconfig.shadowTiddlers.TabTimelineComments = "<<tiddlerComments>>";\n\nconfig.macros.tiddlerComments = {\n dateFormat: 'DD MMM YYYY',\n handler: function(place,macroName,params)\n {\n var field = params[0] ? params[0] : "modified";\n var comments = store.reverseLookup("tags",CPlingo.comments,true,field);\n var lastDay = "";\n for (var c=comments.length-1; c>=0; c--)\n {\n if(comments[c].tags.length == 0) continue;\n var tiddler = get_parent(comments[c]);\n if(!tiddler) continue;\n var theDay = comments[c][field].convertToLocalYYYYMMDDHHMM().substr(0,8);\n if(theDay != lastDay)\n {\n var theDateList = document.createElement("ul");\n place.appendChild(theDateList);\n createTiddlyElement(theDateList,"li",null,"listTitle",comments[c][field].formatString(this.dateFormat));\n lastDay = theDay;\n }\n var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);\n var link = createTiddlyLink(place,comments[c].title);\n link.innerHTML = comments[c].modifier + ' on ' + tiddler.title;\n link.setAttribute("tiddlyLink",tiddler.title);\n theDateListItem.appendChild(link);\n }\n }\n};\n//}}}
/***\n''Name:'' GenRssPlugin\n''Source:'' http://www.sourceforge.net/projects/ptw/\n''Author:'' BramChen\n''Type:'' Plugin\n''Description:''\n<<<\n*This plugin add a "xml-stylesheet" processing to the rss file generated by TW.\n*Required: \n** rssfeed.xsl\n** rssfeed.css\n** xsl.css\n*if 'config.options.txtGenRssTags' is empty then the outputs limited to 'config.numRssItems' except tiddlers taged with 'excludeLists'.\n*you can add the macro {{{<<option txtGenRssTags>>}}} to some configure tiddler, eg 'AdvancedOptions' for changing the tag list,\n*and add {{{<<option txtRssItems>>}}} to change number of rsfeed item.\n<<<\n''Revision History:''\n<<<\nv0.2.0 (Mar 30 2006)\n* add a new feature that rssfeed limited to tiddlers taged with the tag list specified in 'config.options.txtGenRssTags'.\n* add config.options.txtRssItems.\n* if it's empty then the outputs limited to 'config.numRssItems' except tiddlers taged with 'excludeLists'.\n* you can add the macro {{{<<option txtGenRssTags>>}}} to some configure tiddler, eg 'AdvancedOptions' for changing the tag list.\nv0.1.1 (Feb 04 2006)\n* JSLint checked\nv0.1.0 (Feb 1, 2006) \n* initial release\n<<<\n***/\n// //''Code section:''\n//{{{\nversion.extensions.genRss = {major: 0, minor: 2, revision: 0,\n date: new Date("Mar 30, 2006"),\n info: {\n type: "Macro",\n name: "GenRssPlugin",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n }\n};\n\nwindow.generateRss_ori = window.generateRss;\n\nconfig.options.txtGenRssTags = "";\nconfig.options.txtRssItems = "20";\n\nwindow.generateRss = function () {\n var rssTags = config.options.txtGenRssTags.readBracketedList();\n var numRssItems = config.options.txtRssItems;\n var s = [];\n var d = new Date();\n var u = store.getTiddlerText("SiteUrl",null);\n // Assemble the header\n s.push("<" + "?xml version=\s"1.0\s" encoding=\s"utf-8\s"?" + ">");\n s.push("<" + "?xml-stylesheet type=\s"text/xsl\s" href=\s"rss/rssfeed.xsl\s"?" +">");\n s.push("<" + "?xml-stylesheet type=\s"text/css\s" href=\s"rss/rssfeed.css\s"?" +">");\n s.push("<" + "rss version=\s"2.0\s">");\n s.push("<channel>");\n s.push("<title>" + wikifyPlain("SiteTitle").htmlEncode() + "</title>");\n if(u)\n s.push("<link>" + u.htmlEncode() + "</link>");\n s.push("<description>" + wikifyPlain("SiteSubtitle").htmlEncode() + "</description>");\n s.push("<language>en-us</language>");\n s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");\n s.push("<pubDate>" + d.toGMTString() + "</pubDate>");\n s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");\n s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");\n s.push("<generator>TiddlyWiki " + version.major + "." + version.minor + "." + version.revision + "</generator>");\n // The body\n var tiddlers = store.getTiddlers("modified","excludeLists");\n var n = numRssItems > tiddlers.length ? 0 : tiddlers.length-numRssItems;\n for (var t=tiddlers.length-1; t>=n; t--){\n var f=(rssTags.length===0);\n for (var i = 0; i<rssTags.length; i++){\n if (tiddlers[t].tags.find(rssTags[i])!=null){f=true;break;}\n }\n if (f){s.push(tiddlers[t].saveToRss(u));}\n }\n // And footer\n s.push("</channel>");\n s.push("</rss>");\n // Save it all\n return s.join("\sn");\n};\n//}}}
/***\n|''Name:''|LoadExtPlugin|\n|''Description:''|LoadExtPlugin allows you to load external extensions from the file lists (named .js) within those tiddlers taged with "ExtList".|\n|''Version:''|1.8.0|\n|''Date:''|Apr 30, 2007|\n|''Source:''|http://www.sourceforge.net/projects/ptw/|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License]]|\n|''CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n\n+++!^[Revision History:]\nv1.8.0 (Apr 30 2007)\n*config.macros.loadExt support to load singgle external script by using {{{<<loadExt '/pathto/scriptfile.js'>>}}}\n*Ensure LoadExtPlugin loading itself and/or loadling scripts after core has been loaded with external core js and itself|\nv1.7.2 (Sep 28 2006)\n*Fixed bugs on IE\nv1.7.1 (30 Aug 2006)\n* Changed rule check of ExtList\nv1.7.0 (20 Jul 2006)\n* Runs compatibly with TW 2.1.0 (rev #403+)\nv1.6.0 (13 Jul 2006)\n* Fixed bugs in refreshCode and config.macros.loadExt.loadScripts on IE\n* Runs compatibly with TW 2.1.0 (rev #359+)\nv1.5.2 (21 Jun 2006)\n* minor changes for XHTML compliant\nv1.5.1 (26 Feb 2006)\n* JSLint checked\nv1.5.0 (02 Feb 2006)\n* add new function config.macros.loadExt.LoadScripts(), keep all variables to be local, thanks Udo.\n* Fixed several missing variable declarations\nv1.4.0 (20 Jan 2006)\n* refreshCode() improved.\nv1.3.0 (14 Jan 2006) \n* strip startup error massage for IE\nv1.2.0 (13 Jan 2006) \n* TiddlyWiki version 2.0.0 or above required.\n* refreshCode() improved.\nv1.1.0 (10 Jan 2006)\n* To make the extensions list handling more robust, thanks Udo.\n* Fix bugs for multi-tiddlers tagged with ExtList\nv1.0.0 (07 Jan 2006) \n* Combine the RefreshExt code and LoadExtPlugin, and also make TW 1.2 to be backward compatible, thanks Udo.\n* Globle function refreshCode() added, and reserve the refreshExt macro.\n* Fix a minor bug for variable "scriptfile".\nv0.3.0 (29 Dec 2005)\n* macro refreshExt modified to refresh formatter\nv0.2.0 (24 Nov 2005)\n* macro refreshExt modified for TW 1.2.39 beta 2 and above\nv0.1.0 (25 Sep 2005) \n* initial release\n===\n\n!''Code section:''\n***/\n//{{{\nversion.extensions.loadExt = {major: 1, minor: 8, revision: 0,\n date: new Date("Apr 30, 2007"),\n name: "LoadExtPlugin",\n type: "Plugin",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\n\nconfig.macros.loadExt = {};\nconfig.macros.loadExt.handler = function(place,macroName,params){\n if (params[0])\n this.loadScriptFile(params[0]);\n else\n this.loadScripts();\n};\n\nconfig.macros.loadExt.loadScriptFile = function(scriptfile){\n var scriptfile = scriptfile.trim();\n if (scriptfile.length < 2 || scriptfile.substr(0,2) == "//" || scriptfile.indexOf(".js") == -1){\n return;\n }\n // displayMessage("loaded: "+ scriptfile);\n var n = document.createElement("script");\n n.type = "text/javascript";\n n.src = scriptfile;\n document.getElementsByTagName("head")[0].appendChild(n);\n};\n\nconfig.macros.loadExt.loadScripts = function() {\n var extTag = "ExtList";\n var str = ""; var scripts = [];\n var tiddlers = store.getTaggedTiddlers(extTag);\n for(var s=0 ; s<tiddlers.length; s++){\n str += store.getRecursiveTiddlerText(tiddlers[s].title)+"\sn";\n }\n scripts = str.replace(/[;\sr]/mg,"\sn").split("\sn");\n for (var i=0; i<scripts.length-1; i++) {\n this.loadScriptFile(scripts[i]);\n }\n\n if (config.browser.isIE){\n// setTimeout(function(){window.refreshCode();return false;},500);\n var lerInterval = setInterval(function(){if(formatter) {clearInterval(lerInterval); window.refreshCode();};},100);\n }\n else {\n var theCodes = "//<![CDATA[\snwindow.refreshCode();//]]>";\n n = document.createElement("script");\n n.type = "text/javascript";\n n.appendChild(document.createTextNode(theCodes));\n document.getElementsByTagName("head")[0].appendChild(n);\n this.refreshCodeInserted = true;\n }\n};\n\nwindow.refreshCode = function (){\n formatter = new Formatter(config.formatters);\n story.forEachTiddler(function(title,e){story.refreshTiddler(title,DEFAULT_VIEW_TEMPLATE,true);});\n refreshDisplay();\n return false;\n}\n\n// setTimeout(function(){config.macros.loadExt.loadScripts();return false;},500);\nvar loadextpluginInterval = setInterval(function(){if(formatter) {clearInterval(loadextpluginInterval); if(!config.macros.loadExt.refreshCodeInserted) config.macros.loadExt.loadScripts();}},100);\n//}}}
/***\n|Name|NestedSlidersPlugin|\n|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|\n|Version|2.3.1|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides|Slider.prototype.stop|\n|Description|show content in nest-able 'slider' or 'floating' panels, without needing to create separate tiddlers for each panel|\n\n!!!!!Configuration\n<<<\nEnable animation for slider panels\n<<option chkFloatingSlidersAnimate>> allow sliders to animate when opening/closing\n>(note: This setting is in //addition// to the general option for enabling/disabling animation effects:\n><<option chkAnimate>> enable animations (entire document)\n>For slider animation to occur, you must also allow animation in general.\n\nDebugging messages for 'lazy sliders' deferred rendering:\n<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering\n<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered\n<<<\n!!!!!Usage\n<<<\nWhen installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content. Use {{{+++}}} and {{{===}}} to delimit the slider content. You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created. This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.\n\nAdditional optional syntax elements let you specify\n*default to open\n*cookiename\n*heading level\n*floater (with optional CSS width value)\n*transient display (clicking elsewhere closes panel)\n*custom class/label/tooltip/accesskey\n*alternate label/tooltip (displayed when panel is open)\n*panelID (for later use with {{{<<DOM>>}}} macro. See [[DOMTweaksPlugin]])\n*automatic blockquote style on panel\n*deferred rendering of panel content\nThe complete syntax, using all options, is:\n//{{{\n++++(cookiename)!!!!!^width^*{{class{[label=key|tooltip][altlabel|alttooltip]}}}#panelID:>...\ncontent goes here\n===\n//}}}\nwhere:\n* {{{+++}}} (or {{{++++}}}) and {{{===}}}<br>marks the start and end of the slider definition, respectively. When the extra {{{+}}} is used, the slider will be open when initially displayed.\n* {{{(cookiename)}}}<br>saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.\n* {{{!}}} through {{{!!!!!}}}<br>displays the slider label using a formatted headline (Hn) style instead of a button/link style\n* {{{^width^}}} (or just {{{^}}})<br>makes the slider 'float' on top of other content rather than shifting that content downward. 'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.). If omitted, the default width is "auto" (i.e., fit to content)\n* {{{"*"}}} //(without the quotes)//<br>denotes "transient display": when a click occurs elsewhere in the document, the slider/floating panel will be automatically closed. This is useful for creating 'pulldown menus' that automatically go away after they are used.\n* """{{class{[label=key|tooltip][altlabel|alttooltip]}}}"""<br>uses label/tooltip/accesskey. """{{class{...}}}""", """=key""", """|tooltip""" and """[altlabel|alttooltip]""" are optional. 'class' is any valid CSS class name, used to style the slider label text. 'key' must be a ''single letter only''. altlabel/alttooltip specifiy alternative label/tooltip for use when slider/floating panel is displayed.\n* {{{#panelID:}}}<br>defines a unique DOM element ID that is assigned to the panel element used to display the slider content. This ID can then be used later to reposition the panel using the {{{<<DOM move id>>}}} macro (see [[DOMTweaksPlugin]]), or to access/modify the panel element through use of {{{document.getElementById(...)}}}) javascript code in a plugin or inline script.\n* {{{">"}}} //(without the quotes)//<br>automatically adds blockquote formatting to slider content\n* {{{"..."}}} //(without the quotes)//<br>defers rendering of closed sliders until the first time they are opened. //Note: deferred rendering may produce unexpected results in some cases. Use with care.//\n\n//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//\n<<<\n!!!!!Examples\n<<<\nsimple in-line slider: \n{{{\n+++\n content\n===\n}}}\n+++\n content\n===\n----\nuse a custom label and tooltip: \n{{{\n+++[label|tooltip]\n content\n===\n}}}\n+++[label|tooltip]\n content\n===\n----\ncontent automatically blockquoted: \n{{{\n+++>\n content\n===\n}}}\n+++>\n content\n===\n----\nall options combined //(default open, cookie, heading, sized floater, transient, class, label/tooltip/key, blockquoted, deferred)//\n{{{\n++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...\n content\n===\n}}}\n++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...\n content\n===\n----\ncomplex nesting example:\n{{{\n+++[get info...=I|click for information or press Alt-I]\n put some general information here,\n plus a floating panel with more specific info:\n +++^10em^[view details...|click for details]\n put some detail here, which could in turn contain a transient panel,\n perhaps with a +++^25em^*[glossary definition]explaining technical terms===\n ===\n===\n}}}\n+++[get info...=I|click for information or press Alt-I]\n put some general information here,\n plus a floating panel with more specific info:\n +++^10em^[view details...|click for details]\n put some detail here, which could in turn contain a transient panel,\n perhaps with a +++^25em^*[glossary definition]explaining technical terms===\n ===\n===\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2007.07.26 - 2.3.1'' in document.onclick(), propagate return value from hijacked core click handler to consume OR bubble up click as needed. Fixes "IE click disease", whereby nearly every mouse click causes a page transition.\n''2007.07.20 - 2.3.0'' added syntax for setting panel ID (#panelID:). This allows individual slider panels to be repositioned within tiddler content simply by giving them a unique ID and then moving them to the desired location using the {{{<<DOM move id>>}}} macro.\n''2007.07.19 - 2.2.0'' added syntax for alttext and alttip (button label and tooltip to be displayed when panel is open)\n''2007.07.14 - 2.1.2'' corrected use of 'transient' attribute in IE to prevent (non-recursive) infinite loop\n''2007.07.12 - 2.1.0'' replaced use of "*" for 'open/close on rollover' (which didn't work too well). "*" now indicates 'transient' panels that are automatically closed if a click occurs somewhere else in the document. This permits use of nested sliders to create nested "pulldown menus" that automatically disappear after interaction with them has been completed. Also, in onClickNestedSlider(), use "theTarget.sliderCookie", instead of "this.sliderCookie" to correct cookie state tracking when automatically dismissing transient panels.\n''2007.06.10 - 2.0.5'' add check to ensure that window.adjustSliderPanel() is defined before calling it (prevents error on shutdown when mouse event handlers are still defined)\n''2007.05.31 - 2.0.4'' add handling to invoke adjustSliderPanel() for onmouseover events on slider button and panel. This allows the panel position to be re-synced when the button position shifts due to changes in unrelated content above it on the page. (thanks to Harsha for bug report)\n''2007.03.30 - 2.0.3'' added chkFloatingSlidersAnimate (default to FALSE), so that slider animation can be disabled independent of the overall document animation setting (avoids strange rendering and focus problems in floating panels)\n''2007.03.01 - 2.0.2'' for TW2.2+, hijack Morpher.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends\n''2007.03.01 - 2.0.1'' in hijack for Slider.prototype.stop, use apply() to pass params to core function\n|please see [[NestedSlidersPluginHistory]] for additional revision details|\n''2005.11.03 - 1.0.0'' initial public release\n<<<\n!!!!!Credits\n<<<\nThis feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.nestedSliders = {major: 2, minor: 3, revision: 1, date: new Date(2007,7,26)};\n//}}}\n\n//{{{\n// options for deferred rendering of sliders that are not initially displayed\nif (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;\nif (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;\nif (config.options.chkFloatingSlidersAnimate==undefined) config.options.chkFloatingSlidersAnimate=false;\n\n// default styles for 'floating' class\nsetStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \s\n background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");\n//}}}\n\n//{{{\nconfig.formatters.push( {\n name: "nestedSliders",\n match: "\s\sn?\s\s+{3}",\n terminator: "\s\ss*\s\s={3}\s\sn?",\n lookahead: "\s\sn?\s\s+{3}(\s\s+)?(\s\s([^\s\s)]*\s\s))?(\s\s!*)?(\s\s^(?:[^\s\s^\s\s*\s\s[\s\s>]*\s\s^)?)?(\s\s*)?(?:\s\s{\s\s{([\s\sw]+[\s\ss\s\sw]*)\s\s{)?(\s\s[[^\s\s]]*\s\s])?(\s\s[[^\s\s]]*\s\s])?(?:\s\s}{3})?(\s\s#[^:]*\s\s:)?(\s\s>)?(\s\s.\s\s.\s\s.)?\s\ss*",\n handler: function(w)\n {\n lookaheadRegExp = new RegExp(this.lookahead,"mg");\n lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart)\n {\n // var defopen=lookaheadMatch[1]\n // var cookiename=lookaheadMatch[2]\n // var header=lookaheadMatch[3]\n // var panelwidth=lookaheadMatch[4]\n // var transient=lookaheadMatch[5]\n // var class=lookaheadMatch[6]\n // var label=lookaheadMatch[7]\n // var openlabel=lookaheadMatch[8]\n // var panelID=lookaheadMatch[9]\n // var blockquote=lookaheadMatch[10]\n // var deferred=lookaheadMatch[11]\n\n // location for rendering button and panel\n var place=w.output;\n\n // default to closed, no cookie, no accesskey, no alternate text/tip\n var show="none"; var cookie=""; var key="";\n var closedtext=">"; var closedtip="";\n var openedtext="<"; var openedtip="";\n\n // extra "+", default to open\n if (lookaheadMatch[1]) show="block";\n\n // cookie, use saved open/closed state\n if (lookaheadMatch[2]) {\n cookie=lookaheadMatch[2].trim().slice(1,-1);\n cookie="chkSlider"+cookie;\n if (config.options[cookie]==undefined)\n { config.options[cookie] = (show=="block") }\n show=config.options[cookie]?"block":"none";\n }\n\n // parse label/tooltip/accesskey: [label=X|tooltip]\n if (lookaheadMatch[7]) {\n var parts=lookaheadMatch[7].trim().slice(1,-1).split("|");\n closedtext=parts.shift();\n if (closedtext.substr(closedtext.length-2,1)=="=") \n { key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }\n openedtext=closedtext;\n if (parts.length) closedtip=openedtip=parts.join("|");\n else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }\n }\n\n // parse alternate label/tooltip: [label|tooltip]\n if (lookaheadMatch[8]) {\n var parts=lookaheadMatch[8].trim().slice(1,-1).split("|");\n openedtext=parts.shift();\n if (parts.length) openedtip=parts.join("|");\n else openedtip="hide "+openedtext;\n }\n\n var title=show=='block'?openedtext:closedtext;\n var tooltip=show=='block'?openedtip:closedtip;\n\n // create the button\n if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link\n var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;\n var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,lookaheadMatch[6],title);\n btn.onclick=onClickNestedSlider;\n btn.setAttribute("href","javascript:;");\n btn.setAttribute("title",tooltip);\n }\n else\n var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,lookaheadMatch[6]);\n btn.innerHTML=title; // enables use of HTML entities in label\n\n // set extra button attributes\n btn.setAttribute("closedtext",closedtext);\n btn.setAttribute("closedtip",closedtip);\n btn.setAttribute("openedtext",openedtext);\n btn.setAttribute("openedtip",openedtip);\n btn.sliderCookie = cookie; // save the cookiename (if any) in the button object\n btn.defOpen=lookaheadMatch[1]!=null; // save default open/closed state (boolean)\n btn.keyparam=key; // save the access key letter ("" if none)\n if (key.length) {\n btn.setAttribute("accessKey",key); // init access key\n btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus\n }\n btn.onmouseover=function(event) // mouseover on button aligns floater position with button\n { if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel,this.sliderPanel.className); }\n\n // create slider panel\n var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";\n var panelID=lookaheadMatch[9]; if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters\n var panel=createTiddlyElement(place,"div",panelID,panelClass,null);\n panel.button = btn; // so the slider panel know which button it belongs to\n btn.sliderPanel=panel; // so the button knows which slider panel it belongs to\n panel.defaultPanelWidth=(lookaheadMatch[4] && lookaheadMatch[4].length>2)?lookaheadMatch[4].slice(1,-1):"";\n panel.setAttribute("transient",lookaheadMatch[5]=="*"?"true":"false");\n panel.style.display = show;\n panel.style.width=panel.defaultPanelWidth;\n panel.onmouseover=function(event) // mouseover on panel aligns floater position with button\n { if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this,this.className); }\n\n // render slider (or defer until shown) \n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n if ((show=="block")||!lookaheadMatch[11]) {\n // render now if panel is supposed to be shown or NOT deferred rendering\n w.subWikify(lookaheadMatch[10]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);\n // align floater position with button\n if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel,panelClass);\n }\n else {\n var src = w.source.substr(w.nextMatch);\n var endpos=findMatchingDelimiter(src,"+++","===");\n panel.setAttribute("raw",src.substr(0,endpos));\n panel.setAttribute("blockquote",lookaheadMatch[10]?"true":"false");\n panel.setAttribute("rendered","false");\n w.nextMatch += endpos+3;\n if (w.source.substr(w.nextMatch,1)=="\sn") w.nextMatch++;\n if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\sn\sn"+panel.getAttribute("raw"));\n }\n }\n }\n }\n)\n\n// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)\nfunction findMatchingDelimiter(src,starttext,endtext) {\n var startpos = 0;\n var endpos = src.indexOf(endtext);\n // check for nested delimiters\n while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {\n // count number of nested 'starts'\n var startcount=0;\n var temp = src.substring(startpos,endpos-1);\n var pos=temp.indexOf(starttext);\n while (pos!=-1) { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }\n // set up to check for additional 'starts' after adjusting endpos\n startpos=endpos+endtext.length;\n // find endpos for corresponding number of matching 'ends'\n while (startcount && endpos!=-1) {\n endpos = src.indexOf(endtext,endpos+endtext.length);\n startcount--;\n }\n }\n return (endpos==-1)?src.length:endpos;\n}\n//}}}\n\n//{{{\nwindow.onClickNestedSlider=function(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var theLabel = theTarget.firstChild.data;\n var theSlider = theTarget.sliderPanel\n var isOpen = theSlider.style.display!="none";\n\n // toggle label\n theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");\n // toggle tooltip\n theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));\n\n // deferred rendering (if needed)\n if (theSlider.getAttribute("rendered")=="false") {\n if (config.options.chkDebugLazySliderRender)\n alert("rendering '"+theLabel+"':\sn\sn"+theSlider.getAttribute("raw"));\n var place=theSlider;\n if (theSlider.getAttribute("blockquote")=="true")\n place=createTiddlyElement(place,"blockquote");\n wikify(theSlider.getAttribute("raw"),place);\n theSlider.setAttribute("rendered","true");\n }\n // show/hide the slider\n if(config.options.chkAnimate && (theSlider.className!='floatingPanel' || config.options.chkFloatingSlidersAnimate))\n anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n theSlider.style.display = isOpen ? "none" : "block";\n // reset to default width (might have been changed via plugin code)\n theSlider.style.width=theSlider.defaultPanelWidth;\n // align floater panel position with target button\n if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);\n // if showing panel, set focus to first 'focus-able' element in panel\n if (theSlider.style.display!="none") {\n var ctrls=theSlider.getElementsByTagName("*");\n for (var c=0; c<ctrls.length; c++) {\n var t=ctrls[c].tagName.toLowerCase();\n if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")\n { ctrls[c].focus(); break; }\n }\n }\n var cookie=theTarget.sliderCookie;\n if (cookie && cookie.length) {\n config.options[cookie]=!isOpen;\n if (config.options[cookie]!=theTarget.defOpen)\n saveOptionCookie(cookie);\n else { // remove cookie if slider is in default display state\n var ex=new Date(); ex.setTime(ex.getTime()-1000);\n document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();\n }\n }\n return false;\n}\n//}}}\n\n//{{{\n// click in document background closes transient panels \ndocument.nestedSliders_savedOnClick=document.onclick;\ndocument.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);\n // call original click handler\n if (document.nestedSliders_savedOnClick)\n var retval=document.nestedSliders_savedOnClick.apply(this,arguments);\n // if click was inside transient panel (or something contained by a transient panel)... leave it alone\n var p=target;\n while (p)\n if ((p.className=="floatingPanel"||p.className=="sliderPanel")&&p.getAttribute("transient")=="true") break;\n else p=p.parentNode;\n if (p) return retval;\n // otherwise, find and close all transient panels...\n var all=document.all?document.all:document.getElementsByTagName("DIV");\n for (var i=0; i<all.length; i++) {\n // if it is not a transient panel, or the click was on the button that opened this panel, don't close it.\n if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;\n // otherwise, if the panel is currently visible, close it by clicking it's button\n if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button}) \n }\n return retval;\n};\n//}}}\n\n//{{{\n// adjust floating panel position based on button position\nif (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {\n if (panelClass=="floatingPanel") {\n var left=0;\n var top=btn.offsetHeight; \n if (place.style.position!="relative") {\n var left=findPosX(btn);\n var top=findPosY(btn)+btn.offsetHeight;\n var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;\n if (p) { left-=findPosX(p); top-=findPosY(p); }\n }\n if (findPosX(btn)+panel.offsetWidth > getWindowWidth()) // adjust position to stay inside right window edge\n left-=findPosX(btn)+panel.offsetWidth-getWindowWidth()+15; // add extra 15px 'fudge factor'\n panel.style.left=left+"px"; panel.style.top=top+"px";\n }\n}\n\nfunction getWindowWidth() {\n if(document.width!=undefined)\n return document.width; // moz (FF)\n if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )\n return document.documentElement.clientWidth; // IE6\n if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )\n return document.body.clientWidth; // IE4\n if(window.innerWidth!=undefined)\n return window.innerWidth; // IE - general\n return 0; // unknown\n}\n//}}}\n\n//{{{\n// TW2.1 and earlier:\n// hijack Slider animation handler 'stop' handler so overflow is visible after animation has completed\nSlider.prototype.coreStop = Slider.prototype.stop;\nSlider.prototype.stop = function()\n { this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }\n\n// TW2.2+\n// hijack Morpher animation handler 'stop' handler so overflow is visible after animation has completed\nif (version.major+.1*version.minor+.01*version.revision>=2.2) {\n Morpher.prototype.coreStop = Morpher.prototype.stop;\n Morpher.prototype.stop = function()\n { this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }\n}\n//}}}
/***\n!Metadata:\n|''Name:''|RecentTiddlersPlugin|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''Version:''|1.1.1|\n|''Date:''|Aug 28, 2007|\n|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|\n|''~CoreVersion:''|2.1.0|\n|''Description:''|Display DefaultTiddlers and recently modified tiddlers at startup.|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0; Opera|\n!Usage:\n>Just to set the options by changing the slice values in RecentTiddlersOptions, if needed.\n!Revision History:\n|''Version''|''Date''|''Note''|\n|1.1.1|Aug 28, 2007|No more hijeck core restart()|\n|1.1.0|Aug 25, 2007|Easy to change the options by using tiddler slices, defined in RecentTiddlersOptions|\n|1.0.0|Apr 18, 2007|Initial release, codes reworked from Tim Morgan's RecentPlugin |\n!Code section:\n***/\n//{{{\nversion.extensions.recentTiddlers = {major: 1, minor: 1, revision: 1, date: new Date("Aug 28, 2007")};\n\nconfig.recentTiddlers = {\n maxNums: 5,\n includeTags: ['*'],\n excludeTags: ['systemConfig','systemTiddlers', 'excludeLists']\n};\n\nconfig.shadowTiddlers.RecentTiddlersOptions = 'maxNums: 5\snincludeTags: *\snexcludeTags: systemConfig,systemTiddlers,excludeLists';\n\nconfig.recentTiddlers.getRecents = function (){\n var c = store.getTiddlerSlices('RecentTiddlersOptions',['maxNums','includeTags','excludeTags']);\n var maxNums = (c.maxNums) ? parseInt(c.maxNums) : config.recentTiddlers.maxNums;\n var includeTags = (c.includeTags) ? c.includeTags.split(',') : config.recentTiddlers.includeTags;\n var excludeTags = (c.excludeTags) ? c.excludeTags.split(',') : config.recentTiddlers.excludeTags;\n var CPlingo = (config.CommentPlugin !== undefined)?config.CommentPlugin.CPlingo:null;\n var rs = store.getTiddlerText("DefaultTiddlers").readBracketedList();\n var tiddlers = store.getTiddlers("modified");\n var n = tiddlers.length -1 - maxNums;\n\n for (var t=tiddlers.length-1; t>n && t>0; t--){\n if(CPlingo !== null && tiddlers[t].isTagged(CPlingo.comments)) {\n var tt = tiddlers[t].title.split(CPlingo.CommentInTitle)[0];\n if(store.tiddlerExists(tt))\n rs.pushUnique(tt);\n }\n else {\n if (tiddlers[t].tags.containsAny(excludeTags))\n n--;\n else {\n if (includeTags.length == 0 || includeTags[0] == '*' || tiddlers[t].tags.containsAny(includeTags))\n rs.pushUnique(tiddlers[t].title);\n }\n }\n }\n return rs;\n};\n\nif(!window.location.hash)\n var recentInterval = setInterval(function(){if(story) {clearInterval(recentInterval); story.closeAllTiddlers();story.displayTiddlers(null,config.recentTiddlers.getRecents());};},100);\n\n//}}}
/***\n!Metadata:\n|''Name:''|XMLReader|\n|''Description:''||\n|''Version:''|2.2.0|\n|''Date:''|May 19, 2007|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License]]|\n|''~CoreVersion:''|2.2.0|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n|''Required:''|As the param "asHtml" is used, [[NestedSlidersPlugin|http://www.tiddlytools.com/#NestedSlidersPlugin]] should be installed|\n!Syntax:\n{{{<<rssfeed withDesc|noDesc|asHtml rssfeed.xml|http://www.example.com/rssfeed.rdf>>}}}\n!Revision History:\n|''Version''|''Date''|''Note''|\n|2.2.0|May 19, 2007|Atom feeds suppported|\n|2.1.1|May 15, 2007|Fixed cache bug|\n|2.1.0|May 10, 2007|Fixed bugs:<br>1.missing parameter 'responseText' of processResponse<br>2.Caches failed|\n|2.0.0|Mar 08, 2007|Required TW 2.2.0+|\n|1.5.0|Mar 04, 2007|Codes reworked, more easier reused|\n|1.2.0|Jul 20, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|\n|1.1.0|Jul 10, 2006)|change xmlhttp.send(null)/send() to xmlhttp.send("") for more compatibility for some browsers|\n|1.0.0|Mar 11, 2006|Initial release|\n|~|~|This macro is reworked from RssNewsMacro, but it can be easy to extended to support different structure of xml document from rss feeds|\n|~|~|You could uninstall the RssNewsMacro, but still use the original syntax,<<br>>{{{<<rssfeed withDesc|noDesc|asHtml "rssfeed.xml"|"http://www.example.com/rssfeed.rdf">>}}}|\n\n!Code section:\n***/\n//{{{\nversion.extensions.xmlreader = {major: 2, minor: 2, revision: 0,\n date: new Date("May 19, 2007"),\n name: "XMLReader",\n type: "Macro",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\n\nconfig.messages.XmlReader = {\n fromCache: "^^(//from cache//)^^",\n errorInDataRetriveing: "Problem retrieving XML data: %0",\n invalidXML: "Invalid XML retrieved from: %0",\n urlNotAccessible: "Access to %0 is not allowed,\snPlease check the setting of your browser:\sn1.For Gecko based, you should set the 'signed.applets.codebase_principal_support' to be true, in about:config.\sn2.For IE, you should add this web site to your trust list."\n};\n\nfunction XmlReader(place,withDesc,xmlURL) {\n this.xmlhttp = null;\n this.place = place;\n this.xmlURL = xmlURL;\n this.withDesc = withDesc;\n this.itemStructure = {title:'Title',link:'Link',pubDate:'PubDate',description:'Desc'};\n this.atomStructure = {title:'Title',id:'Link',updated:'Updated',summary:'Desc'};\n// this.rsTemplate = function(){var t='';for (var i in itemStructure){t+='_'+itemStructure[i]}};\n this.rsTemplate = '_pubDate\sn**[[_title|_link]]_description';\n this.items = {Elm: "%0Elm", Text: "_%0"};\n this.keyItem = "item";\n this.dateFormat = "DDD, DD MMM YYYY";\n this.groupBy = null;\n return this;\n};\n\nXmlReader.prototype.asyncGet = function(xmlURL,callback){\n if(window.Components && window.netscape && window.netscape.security && this.isCrossSite(xmlURL)){\n try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");}\n catch (e) {displayMessage(e.description?e.description:e.toString());}\n }\n return doHttp("GET",xmlURL,null,'text/xml',null,null,callback,null,null)\n};\n\nXmlReader.prototype.genLists = function(xml){\n var itemStructure;\n if (xml.lastChild.nodeName == 'feed'){\n this.keyItem = 'entry';\n itemStructure = this.atomStructure;\n }\n else {\n itemStructure = this.itemStructure;\n }\n var itemList = xml.getElementsByTagName(this.keyItem);\n var items = this.items;\n var rsLists='', rssItem; this.groupBy='';\n for (var i=0; i<itemList.length; i++){\n var itemElms=[],itemTexts=[];\n var rsTemplate=this.rsTemplate;\n for (var j in itemStructure){\n var itemElm = items.Elm.format([j]);\n var itemText = items.Text.format([j]);\n itemElms[itemElm] = itemList[i].getElementsByTagName(j).item(0);\n if(itemElms[itemElm]){\n var theTitle = itemStructure[j];\n var theText = (itemElms[itemElm].firstChild)?itemElms[itemElm].firstChild.nodeValue:'';\n rsTemplate=this.convertTemplate(rsTemplate,j,theText);\n }\n else {\n rsTemplate = rsTemplate.replace('_'+j, '');\n }\n }\n rsLists += rsTemplate;\n }\n return rsLists;\n};\n \nXmlReader.prototype.convertTemplate = function(rsTemplate,j,theText){\n switch (j){\n case 'title':\n rsTemplate = rsTemplate.replace(/_title/,theText.replace(/\s[|\s]/g,''));\n break;\n case 'id':\n j = 'link';\n case 'link' || 'id':\n rsTemplate = rsTemplate.replace('_'+j, theText);\n break;\n case 'updated':\n j = 'pubDate'\n case 'pubDate':\n theText = this.dateFormatString(this.dateFormat, theText);\n if (this.groupBy == theText){\n rsTemplate = rsTemplate.replace('_'+j, '');\n }\n else{\n rsTemplate = rsTemplate.replace('_'+j, '\sn* '+theText);\n this.groupBy = theText;\n }\n break;\n case 'summary':\n j = 'description';\n case 'description':\n var regexpDesc = new RegExp("withDesc|asHtml","g");\n if (regexpDesc.exec(this.withDesc) && theText){\n var _description = theText.replace(/\sn/g,' ');\n _description =_description.replace(/<br \s/>/ig,'\sn'); \n if (version.extensions.nestedSliders){\n _description = ((this.withDesc == "asHtml")?"<html>"+_description+"</html>":_description);\n rsTemplate = rsTemplate.replace('_'+j,'+++[...]'+_description+'\sn===\sn');\n }\n else {\n rsTemplate = rsTemplate.replace('_'+j,_description+'\sn');\n }\n }\n else {\n rsTemplate = rsTemplate.replace('_'+j,'');\n }\n break;\n }\n return (rsTemplate);\n};\n\nXmlReader.prototype.dateFormatString = function(template, theDate){\n theDate = theDate.replace(/-/g,'/').replace(/T.*UT|T.*Z/ ,'');\n var dateString = new Date(theDate);\n template = template.replace(/hh|mm|ss/g,'');\n return dateString.formatString(template);\n};\n\nXmlReader.prototype.isCrossSite = function (url){\n var result = false;\n var curLoc = document.location;\n if (url.indexOf(":") != -1 && curLoc.protocol.indexOf("http") != -1) {\n var re=/(\sw+):\s/\s/([^/:]+)(:\sd*)?([^# ]*)/;\n var rsURL=url.match(re);\n for (var i=0; i<rsURL.length; i++){\n rsURL[i]=(typeof rsURL[i] == 'undefined')?'':rsURL[i];\n }\n result = (curLoc.protocol == rsURL[1] && curLoc.host == rsURL[2] && curLoc.port == rsURL[3]);\n }\n return (!result);\n};\n//}}}\n/***\n!Macro rssfeed\n***/\n//{{{\nconfig.macros.rssfeed = {\n cache: {},\n dateFormat: "YYYY/0MM/0DD"\n};\n\nconfig.macros.rssfeed.handler = function(place,macroName,params){\n var withDesc = params[0];\n var xmlURL = params[1];\n var rss = new XmlReader(place,withDesc,xmlURL);\n rss.dateFormat = this.dateFormat;\n var processResponse = function(status,params,responseText,xmlURL,x){\n if (window.netscape){\n if (rss.isCrossSite(xmlURL)){\n try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");}\n catch (e) { displayMessage(e.description?e.description:e.toString()); }\n }\n }\n if (x.responseXML){\n xmlURL = xmlURL.replace(/[\s?|\s&]nocache.*/,'');\n config.macros.rssfeed.cache[xmlURL] = x;\n wikify(rss.genLists(x.responseXML),place);\n }\n else {\n wikify("<html>"+ x.responseText+"</html>", place);\n displayMessage(config.messages.XmlReader.invalidXML.format([xmlURL]));\n }\n };\n if (this.cache[xmlURL]) {\n wikify(config.messages.XmlReader.fromCache,place);\n var status = false;\n var x=this.cache[xmlURL];\n processResponse(status,null,x.responseText,xmlURL,x);\n }\n else {\n rss.xmlhttp = rss.asyncGet(xmlURL, processResponse);\n }\n};\n//}}}
/***\n|''Name:''|WikiBar|\n|''Version:''|2.0.0 beta3|\n|''Source:''|[[AiddlyWiki|http://aiddlywiki.sourceforge.net]]|\n|''Author:''|[[Arphen Lin|mailto:arphenlin@gmail.com]]|\n|''Type:''|toolbar macro command extension|\n|''Required:''|TiddlyWiki 2.0.0 beta6|\n!Description\nWikiBar is a toolbar that gives access to most of TiddlyWiki's formatting features with a few clicks. It's a handy tool for people who are not familiar with TiddlyWiki syntax.\nBesides, with WikiBar-addons, users can extend the power of WikiBar.\n!Support browser\n*Firefox 1.5\n!Revision history\n*v2.0.0 beta3 (2005/12/30)\n** remove macros (replaced by TWMacro addon)\n** add wikibar command in toolbar automatically\n** rename DOIT to HANDLER\n** rename TIP to TOOLTIP\n*v2.0.0 beta2 (2005/12/21)\n** re-design Wikibar addon framework\n*v2.0.0 beta1 (2005/12/14)\n** Note:\n*** WikiBarPlugin is renamed to WikiBar\n** New Features:\n*** support TiddlyWiki 2.0.0 template mechanism\n*** new wikibar data structure\n*** new wikibar-addon framework for developers\n**** support dynamic popup menu generator\n*** support most new macros added in TiddlyWiki 2.0.0\n*** multi-level popup menu\n*** fix wikibar tab stop\n*** remove paletteSelector\n** Known Bugs:\n*** popup-menu and color-picker can't be closed correctly\n*** some macros can't be displayed correctly in previewer\n*** text in previewer will be displayed italic\n*v1.2.0 (2005/11/21)\n**New Features:\n***User defined color palettes supported\n####Get color palettes from [[ColorZilla Palettes|http://www.iosart.com/firefox/colorzilla/palettes.html]].\n####Save the palette file(*.gpl) as a new tiddler and tag it with 'ColorPalettes', then you can use it in WikiBar.\n***WikiBar style sheet supported\n***Click on document to close current colorPicker, paletteSelector or aboutWikibar\n*v1.1.1 (2005/11/03)\n**Bugs fixed:\n***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'\n*v1.1.0 (2005/11/01)\n**Bugs fixed:\n***WikiBar overruns (reported by by GeoffS <gslocock@yahoo.co.uk>)\n**New features:\n***Insert a color code at the cursor. (Thanks to RunningUtes <RunningUtes@gmail.com>)\n***Enable gradient macro. (Thanks to RunningUtes <RunningUtes@gmail.com>)\n***Insert tiddler comment tags {{{/% ... %/}}}. (new feature supported by TiddlyWiki 1.2.37)\n***Insert DateFormatString for {{{<<today>>}}} macro. (new feature supported by TiddlyWiki 1.2.37)\n**Enhanced:\n***Allow optional parameters in syntax.\n**Bugs:\n***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'\n*v1.0.0 (2005/10/30)\n**Initial release\n!Code\n***/\n//{{{\nconfig.macros.wikibar = {major: 2, minor: 0, revision: 0, beta: 3, date: new Date(2005,12,30)};\nconfig.macros.wikibar.handler = function(place,macroName,params,wikifier,paramString,tiddler){\n if(!(tiddler instanceof Tiddler)) {return;}\n story.setDirty(tiddler.title,true);\n place.id = 'wikibar'+tiddler.title;\n place.className = 'toolbar wikibar';\n};\nfunction wikibar_install(){\n config.commands.wikibar = {\n text: 'wikibar',\n tooltip: 'wikibar on/off',\n handler: function(e,src,title) {\n if(!e){ e = window.event; }\n var theButton = resolveTarget(e);\n theButton.id = 'wikibarButton'+title;\n wikibarPopup.remove();\n wikibar_installAddons(theButton, title);\n wikibar_createWikibar(title);\n return(false);\n }\n };\n config.shadowTiddlers['EditTemplate'] = wikibar_addWikibarCommand(config.shadowTiddlers['EditTemplate']);\n var tiddler = store.getTiddler('EditTemplate');\n if(tiddler){\n tiddler.text = wikibar_addWikibarCommand(tiddler.text);\n }\n}\nfunction wikibar_installAddons(theButton, title){\n var tiddlers = store.getTaggedTiddlers('wikibarAddons');\n if(!tiddlers) { return; }\n theButton.addons=[];\n for(var i=0; i<tiddlers.length; i++){\n try{\n eval(tiddlers[i].text);\n try{\n wikibar_addonInstall(title);\n wikibar_addonInstall = null;\n theButton.addons.push({ok:true, name:tiddlers[i].title});\n }catch(ex){\n theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});\n }\n }catch(ex){\n theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});\n }\n }\n}\nfunction wikibar_addWikibarCommand(tiddlerText){\n var div = document.createElement('div');\n div.style.display = 'none';\n div.innerHTML = tiddlerText;\n for(var i=0; i<div.childNodes.length; i++){\n var o=div.childNodes[i];\n if(o.tagName==='DIV'){\n if(o.className=='toolbar'){\n var macroText = o.getAttribute('macro').trim();\n if(macroText.search('wikibar')<=0){\n macroText += ' wikibar';\n o.setAttribute('macro', macroText);\n }\n break;\n }\n }\n }\n return div.innerHTML.replace(/\s"/g, "\s'");\n}\nfunction wikibar_processSyntaxParams(theSyntax, params){\n try{\n var pcr = 'AplWikibarPcr';\n var rx=null;\n var allParams=null;\n if(params){\n if(typeof(params)=='object'){\n for(var i=0; i<params.length; i++){\n if(params[i]){\n params[i] = params[i].replace(new RegExp('%','g'), pcr).trim();\n rx = '(\s\s[%'+(i+1)+'\s\s])' + '|' + '(%'+(i+1)+')';\n theSyntax = theSyntax.replace(new RegExp(rx,'g'), params[i] );\n }\n }\n allParams = params.join(' ').trim();\n }else{\n allParams = params.replace(new RegExp('%','g'), pcr).trim();\n rx = /(\s[%1{1}\s])|(%1{1})/g;\n theSyntax = theSyntax.replace(rx, allParams);\n }\n }\n if(allParams){\n theSyntax = theSyntax.replace(new RegExp('%N{1}','g'), allParams);\n }\n rx=/\s[%(([1-9]{1,}[0-9]{0,})|(N{1}))\s]/g;\n theSyntax = theSyntax.replace(rx, '');\n rx=/%(([1-9]{1,}[0-9]{0,})|(N{1}))/g;\n if( theSyntax.match(rx) ){\n throw 'Not enough parameters! ' + theSyntax;\n }\n theSyntax=theSyntax.replace(new RegExp(pcr,'g'), '%');\n return theSyntax;\n } catch(ex){\n return null;\n }\n}\nfunction wikibar_resolveEditItem(tiddlerWrapper, itemName){\n if(tiddlerWrapper.hasChildNodes()){\n var c=tiddlerWrapper.childNodes;\n for(var i=0; i<c.length; i++){\n var txt=wikibar_resolveEditItem(c[i], itemName);\n if(!txt){\n continue;\n }else{\n return txt;\n }\n }\n }\n return ((tiddlerWrapper.getAttribute && tiddlerWrapper.getAttribute('edit')==itemName)? tiddlerWrapper : null);\n}\nfunction wikibar_resolveEditItemValue(tiddlerWrapper, itemName){\n var o = wikibar_resolveEditItem(tiddlerWrapper, itemName);\n return (o? o.value.replace(/\sr/mg,'') : null);\n}\nfunction wikibar_resolveTiddlerEditorWrapper(obj){\n if(obj.id=='tiddlerDisplay'){return null;}\n if((obj.getAttribute && obj.getAttribute('macro')=='edit text')){return obj;}\n return wikibar_resolveTiddlerEditorWrapper(obj.parentNode);\n}\nfunction wikibar_resolveTiddlerEditor(obj){\n if(obj.hasChildNodes()){\n var c = obj.childNodes;\n for(var i=0; i<c.length; i++){\n var o=wikibar_resolveTiddlerEditor(c[i]);\n if(o){ return o;}\n }\n }\n return ((obj.getAttribute && obj.getAttribute('edit')=='text')? obj : null);\n}\nfunction wikibar_resolveTargetButton(obj){\n if(obj.id && obj.id.substring(0,7)=='wikibar'){ return null; }\n if(obj.tiddlerTitle){\n return obj;\n }else{\n return wikibar_resolveTargetButton(obj.parentNode);\n }\n}\nfunction wikibar_isValidMenuItem(tool){\n if(!tool){ return false; }\n if(tool.TYPE=='MENU' || tool.TYPE=='MAIN_MENU'){\n for(var key in tool){\n if(key.substring(0,8)=='DYNAITEM'){ return true; }\n if(wikibar_isValidMenuItem(tool[key])){ return true; }\n }\n return false;\n }else{\n return (tool.HANDLER? true : false);\n }\n}\nfunction wikibar_editFormat(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n else if(ss===0 && (se===0 || se == fullText.length) ){\n endText = fullText;\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByWord(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){return;}\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var selText = '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n frontText = fullText.substring(0, ss);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se, fullText.length);\n }\n else if(ss===0 && (se===0 || se == fullText.length) ){\n endText = fullText;\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n if(!( fullText.charAt(ss-1).match(/\sW/gi) || fullText.charAt(ss).match(/\sW/gi) )){\n var m = frontText.match(/\sW/gi);\n if(m){\n ss = frontText.lastIndexOf(m[m.length-1])+1;\n }\n else{\n ss = 0;\n }\n m = endText.match(/\sW/gi);\n if(m){\n se += endText.indexOf(m[0]);\n }\n else{\n se = fullText.length;\n }\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n selText = fullText.substring(ss,se);\n }\n }\n if(selText.length>0){\n repText = repText.replace('user_text', selText);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByCursor(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n else if(ss===0 && (se===0 || se == fullText.length) ){\n endText = fullText;\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByLine(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var selText = '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n if(this.byBlock){\n frontText = fullText.substring(0, ss);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se, fullText.length);\n }\n else{\n se = ss;\n }\n }\n if(ss===0 && (se===0 || se == fullText.length) ){\n var m=fullText.match(/(\sn|\sr)/g);\n if(m){\n se = fullText.indexOf(m[0]);\n }else{\n se = fullText.length;\n }\n selText = fullText.substring(0, se);\n endText = fullText.substring(se, fullText.length);\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n m = frontText.match(/(\sn|\sr)/g);\n if(m){\n ss = frontText.lastIndexOf(m[m.length-1])+1;\n }\n else{\n ss = 0;\n }\n m = endText.match(/(\sn|\sr)/g);\n if(m){\n se += endText.indexOf(m[0]);\n }\n else{\n se = fullText.length;\n }\n frontText = fullText.substring(0, ss);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se, fullText.length);\n }\n if(selText.length>0){\n repText = repText.replace('user_text', selText);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n if(this.byBlock){\n if( (frontText.charAt(frontText.length-1)!='\sn') && ss>0 ){\n repText = '\sn' + repText;\n }\n if( (endText.charAt(0)!='\sn') || se==fullText.length){\n repText += '\sn';\n }\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByTableCell(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var selText = '';\n var endText = '';\n var fullText = editor.value;\n if(ss===0 || ss==fullText.length){\n throw 'not valid cell!';\n }\n se=ss;\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n i=frontText.lastIndexOf('\sn');\n j=frontText.lastIndexOf('|');\n if(i>j || j<0){\n throw 'not valid cell!';\n }\n ss = j+1;\n i=endText.indexOf('\sn');\n j=endText.indexOf('|');\n if(i<j || j<0){\n throw 'not valid cell!';\n }\n se += j;\n frontText = fullText.substring(0, ss-1);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se+1, fullText.length);\n if(this.key.substring(0,5)=='align'){\n selText = selText.trim();\n if( selText=='>' || selText=='~' || selText.substring(0,8)=='bgcolor(') {return; }\n }\n if(selText.length>0){\n repText = repText.replace('user_text', selText);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length - 2;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editSelectAll(param){\n var editor = param.button.editor;\n editor.selectionStart = 0;\n editor.selectionEnd = editor.value.length;\n editor.scrollTop = 0;\n editor.focus();\n}\nfunction wikibar_doPreview(param){\n var theButton = param.button;\n var editor = param.button.editor;\n var wikibar = theButton.parentNode;\n if(!wikibar) { return; }\n title = theButton.tiddlerTitle;\n var editorWrapper = wikibar_resolveTiddlerEditorWrapper(editor);\n var tiddlerWrapper = editorWrapper.parentNode;\n var previewer = document.getElementById('previewer'+title);\n if(previewer){\n previewer.parentNode.removeChild(previewer);\n editorWrapper.style.display = 'block';\n visible=true;\n }else{\n previewer = document.createElement('div');\n previewer.id = 'previewer'+title;\n previewer.className = 'viewer previewer';\n previewer.style.height = (editor.offsetHeight) + 'px';\n wikify(editor.value, previewer);\n tiddlerWrapper.insertBefore(previewer, editorWrapper);\n editorWrapper.style.display = 'none';\n visible=false;\n }\n var pv=null;\n for(var i=0; i<wikibar.childNodes.length; i++){\n try{\n var btn = wikibar.childNodes[i];\n if(btn.toolItem.key == 'preview'){ pv=btn; }\n if(btn.toolItem.key != 'preview'){\n btn.style.display = visible ? '': 'none';\n }\n }catch(ex){}\n }\n if(!pv) { return; }\n if(visible){\n pv.innerHTML = '<font face=\s"verdana\s">∞</font>';\n pv.title = 'preview current tiddler';\n }\n else{\n pv.innerHTML = '<font face=\s"verdana\s">←</font>';\n pv.title = 'back to editor';\n }\n}\nfunction wikibar_doListAddons(param){\n clearMessage();\n var title = param.button.tiddlerTitle;\n var wikibarButton = document.getElementById('wikibarButton'+title);\n var ok=0, fail=0;\n for(var i=0; i<wikibarButton.addons.length; i++){\n var addon=wikibarButton.addons[i];\n if(addon.ok){\n displayMessage('[ o ] '+addon.name);\n ok++;\n }\n else{\n displayMessage('[ x ] '+addon.name + ': ' + addon.error);\n fail++;\n }\n }\n displayMessage('---------------------------------');\n displayMessage(ok + ' ok ; ' + fail + ' failed');\n}\nfunction wikibar_getColorCode(param){\n var cbOnPickColor = function(colorCode, param){\n param.params = colorCode;\n param.button.toolItem.doMore(param);\n };\n wikibarColorTool.openColorPicker(param.button, cbOnPickColor, param);\n}\nfunction wikibar_getLinkUrl(param){\n var url= prompt('Please enter the link target', (this.param? this.param : ''));\n if (url && url.trim().length>0){\n param.params = url;\n this.doMore(param);\n }\n}\nfunction wikibar_getTableRowCol(param){\n var rc= prompt('Please enter (rows x cols) of the table', '2 x 3');\n if (!rc || (rc.trim()).length<=0){ return; }\n var arr = rc.toUpperCase().split('X');\n if(arr.length != 2) { return; }\n for(var i=0; i<arr.length; i++){\n if(isNaN(arr[i].trim())) { return; }\n }\n var rows = parseInt(arr[0].trim(), 10);\n var cols = parseInt(arr[1].trim(), 10);\n var txtTable='';\n for(var r=0; r<rows; r++){\n for(var c=0; c<=cols; c++){\n if(c===0){\n txtTable += '|';\n }else{\n txtTable += ' |';\n }\n }\n txtTable += '\sn';\n }\n if(txtTable.trim().length>0){\n param.params = txtTable.trim();\n this.doMore(param);\n }\n}\nfunction wikibar_getMacroParam(param){\n var p = prompt('Please enter the parameters of macro \s"' + this.key + '\s":' +\n '\snSyntax: ' + this.syntax +\n '\sn\snNote: '+\n '\sn%1,%2,... - parameter needed'+\n '\sn[%1] - optional parameter'+\n '\sn%N - more than one parameter(1~n)'+\n '\sn[%N] - any number of parameters(0~n)'+\n '\sn\snPS:'+\n '\sn1. Parameters should be seperated with space character'+\n '\sn2. Use \s" to wrap the parameter that includes space character, ex: \s"hello world\s"'+\n '\sn3. Input the word(null) for the optional parameter ignored',\n (this.param? this.param : '') );\n if(!p) { return; }\n p=p.readMacroParams();\n for(var i=0; i<p.length; i++){\n var s=p[i].trim();\n if(s.indexOf(' ')>0){ p[i]="'"+s+"'"; }\n if(s.toLowerCase()=='null'){ p[i]=null; }\n }\n param.params = p;\n this.doMore(param);\n}\nfunction wikibar_getMorePalette(unused){\n clearMessage();\n displayMessage('Get more color palettes(*.gpl) from ColorZilla Palettes site', 'http:\s/\s/www.iosart.com/firefox/colorzilla/palettes.html');\n displayMessage('Save it as a new tiddler with \s"ColorPalettes\s" tag');\n}\nfunction wikibar_createWikibar(title){\n var theWikibar = document.getElementById('wikibar' + title);\n if(theWikibar){\n if(theWikibar.hasChildNodes()){\n theWikibar.style.display = (theWikibar.style.display=='block'? 'none':'block');\n return;\n }\n }\n var tiddlerWrapper = document.getElementById('tiddler'+title);\n var theTextarea = wikibar_resolveTiddlerEditor(tiddlerWrapper);\n if(!theTextarea){\n clearMessage();\n displayMessage('WikiBar only works in tiddler edit mode now');\n return;\n }else{\n if(!theTextarea.id){ theTextarea.id = 'editor'+title; }\n if(!theTextarea.parentNode.id){ theTextarea.parentNode.id='editorWrapper'+title; }\n }\n if(theWikibar){\n theWikibar = document.getElementById('wikibar'+title);\n }else{\n var editorWrapper = wikibar_resolveTiddlerEditorWrapper(theTextarea);\n theWikibar = createTiddlyElement(tiddlerWrapper, 'div', 'wikibar'+title, 'toolbar');\n addClass(theWikibar, 'wikibar');\n var previewer = document.getElementById('previewer'+title);\n if(previewer){\n tiddlerWrapper.insertBefore(theWikibar, previewer);\n }else{\n tiddlerWrapper.insertBefore(theWikibar, editorWrapper);\n }\n }\n wikibar_createMenu(theWikibar,wikibarStore,title,theTextarea);\n if(config.options['chkWikibarSetEditorHeight'] && config.options['txtWikibarEditorRows']){\n theTextarea.rows = config.options['txtWikibarEditorRows'];\n }\n setStylesheet(\n '.wikibar{text-align:left;visibility:visible;margin:2px;padding:1px;}.previewer{overflow:auto;display:block;border:1px solid;}#colorPicker{position:absolute;display:none;z-index:10;margin:0px;padding:0px;}#colorPicker table{margin:0px;padding:0px;border:2px solid #000;border-spacing:0px;border-collapse:collapse;}#colorPicker td{margin:0px;padding:0px;border:1px solid;font-size:11px;text-align:center;cursor:auto;}#colorPicker .header{background-color:#fff;}#colorPicker .button{background-color:#fff;cursor:pointer;cursor:hand;}#colorPicker .button:hover{padding-top:3px;padding-bottom:3px;color:#fff;background-color:#136;}#colorPicker .cell{padding:4px;font-size:7px;cursor:crosshair;}#colorPicker .cell:hover{padding:10px;}.wikibarPopup{position:absolute;z-index:10;border:1px solid #014;color:#014;background-color:#cef;}.wikibarPopup table{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;}.wikibarPopup .button:hover{color:#eee;background-color:#014;}.wikibarPopup .disabled{color:#888;}.wikibarPopup .disabled:hover{color:#888;background-color:#cef;}.wikibarPopup tr .seperator hr{margin:0;padding:0;background-color:#cef;width:100%;border:0;border-top:1px dashed #014;}.wikibarPopup tr .icon{font-family:verdana;font-weight:bolder;}.wikibarPopup tr .marker{font-family:verdana;font-weight:bolder;}.wikibarPopup td{font-size:0.9em;padding:2px;}.wikibarPopup input{border:0;border-bottom:1px solid #014;margin:0;padding:0;font-family:arial;font-size:100%;background-color:#fff;}',\n 'WikiBarStyleSheet');\n}\nfunction wikibar_createMenu(place,toolset,title,editor){\n if(!wikibar_isValidMenuItem(toolset)){return;}\n if(!(toolset.TYPE=='MAIN_MENU' || toolset.TYPE=='MENU')){ return; }\n for(var key in toolset){\n if(key.substring(0,9)=='SEPERATOR'){\n wikibar_createMenuSeperator(place);\n continue;\n }\n if(key.substring(0,8)=='DYNAITEM'){\n var dynaTools = toolset[key](title,editor);\n if(dynaTools.TYPE && dynaTools.TYPE=='MENU'){\n wikibar_createMenuItem(place,dynaTools,null,editor,title);\n }else{\n dynaTools.TYPE = 'MENU';\n wikibar_createMenu(place, dynaTools, title, editor);\n }\n continue;\n }\n if((toolset[key].TYPE!='MENU' && toolset[key].TYPE!='MAIN_MENU') && !toolset[key].HANDLER){continue;}\n wikibar_createMenuItem(place,toolset,key,editor,title);\n }\n}\nfunction wikibar_createMenuItem(place,toolset,key,editor,title){\n if(!key){\n var tool = toolset;\n }else{\n tool = toolset[key];\n tool.key = key;\n }\n if(!wikibar_isValidMenuItem(tool)){return;}\n var toolIsOnMainMenu = (toolset.TYPE=='MAIN_MENU');\n var toolIsMenu = (tool.TYPE=='MENU');\n var theButton;\n if(toolIsOnMainMenu){\n theButton = createTiddlyButton(\n place,\n '',\n (tool.TOOLTIP? tool.TOOLTIP : ''),\n (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem),\n 'button');\n theButton.innerHTML = (tool.CAPTION? tool.CAPTION : key);\n theButton.isOnMainMenu = true;\n addClass(theButton, (toolIsMenu? 'menu' : 'item'));\n place.appendChild( document.createTextNode('\sn') );\n if(!toolIsMenu){\n if(config.options['chkWikibarPopmenuOnMouseOver']){\n theButton.onmouseover = function(e){ wikibarPopup.remove(); };\n }\n }\n }else{\n theButton=createTiddlyElement(place, 'tr',key,'button');\n theButton.title = (tool.TOOLTIP? tool.TOOLTIP : '');\n theButton.onclick = (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem);\n var tdL = createTiddlyElement(theButton, 'td','','marker');\n var td = createTiddlyElement(theButton, 'td');\n var tdR = createTiddlyElement(theButton, 'td','','marker');\n td.innerHTML = (tool.CAPTION? tool.CAPTION : key);\n if(toolIsMenu){\n tdR.innerHTML=' ›';\n }\n if(tool.SELECTED){\n tdL.innerHTML = '√ ';\n addClass(theButton, 'selected');\n }\n if(tool.DISABLED){\n addClass(theButton, 'disabled');\n }\n }\n theButton.tiddlerTitle = title;\n theButton.toolItem = tool;\n theButton.editor = editor;\n theButton.tabIndex = 999;\n if(toolIsMenu){\n if(config.options['chkWikibarPopmenuOnMouseOver']){\n theButton.onmouseover = wikibar_onClickMenuItem;\n }\n }\n}\nfunction wikibar_createMenuSeperator(place){\n if(place.id.substring(0,7)=='wikibar') { return; }\n var onclickSeperator=function(e){\n if(!e){ e = window.event; }\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n return(false);\n };\n var theButton=createTiddlyElement(place,'tr','','seperator');\n var td = createTiddlyElement(theButton, 'td','','seperator');\n td.colSpan=3;\n theButton.onclick=onclickSeperator;\n td.innerHTML = '<hr>';\n}\nfunction wikibar_genWikibarAbout(){\n var toolset={};\n toolset.version = {\n CAPTION: '<center>WikiBar ' +\n config.macros.wikibar.major + '.' +\n config.macros.wikibar.minor + '.' +\n config.macros.wikibar.revision +\n (config.macros.wikibar.beta? ' beta '+config.macros.wikibar.beta : '') +\n '</center>',\n HANDLER: function(){}\n };\n toolset.SEPERATOR = {};\n toolset.author = {\n CAPTION: '<center>Arphen Lin<br>arphenlin@gmail.com</center>',\n TOOLTIP: 'send mail to the author',\n HANDLER: function(){ window.open('mailto:arphenlin@gmail.com'); }\n };\n toolset.website = {\n CAPTION: '<center>aiddlywiki.sourceforge.net</center>',\n TOOLTIP: 'go to the web site of WikiBar',\n HANDLER: function(){ window.open('http:\s/\s/aiddlywiki.sourceforge.net/'); }\n };\n return toolset;\n}\nfunction wikibar_genWikibarOptions(title, editor){\n var toolset={};\n toolset.popOnMouseOver = {\n CAPTION:'popup menu on mouse over',\n SELECTED: config.options['chkWikibarPopmenuOnMouseOver'],\n HANDLER: function(param){\n config.options['chkWikibarPopmenuOnMouseOver'] = !config.options['chkWikibarPopmenuOnMouseOver'];\n saveOptionCookie('chkWikibarPopmenuOnMouseOver');\n var title = param.button.tiddlerTitle;\n var wikibar = document.getElementById('wikibar'+title);\n if(wikibar){ wikibar.parentNode.removeChild(wikibar); }\n wikibar_createWikibar(title);\n }\n };\n toolset.setEditorSize = {\n CAPTION:'set editor height: <input id=\s"txtWikibarEditorRows\s" type=text size=1 MAXLENGTH=3 value=\s"' +\n (config.options['txtWikibarEditorRows']? config.options['txtWikibarEditorRows']:editor.rows) + '\s"> ok',\n HANDLER: function(param){\n var input = document.getElementById('txtWikibarEditorRows');\n if(input){\n var rows = parseInt(input.value, 10);\n if(!isNaN(rows)){\n var editor = param.button.editor;\n editor.rows = rows;\n }else{\n rows=config.maxEditRows;\n }\n config.options['txtWikibarEditorRows'] = rows;\n saveOptionCookie('txtWikibarEditorRows');\n config.maxEditRows = rows;\n }\n }\n };\n toolset.setEditorSizeOnLoadingWikibar = {\n CAPTION:'set editor height on loading wikibar',\n SELECTED: config.options['chkWikibarSetEditorHeight'],\n HANDLER: function(param){\n config.options['chkWikibarSetEditorHeight'] = !config.options['chkWikibarSetEditorHeight'];\n saveOptionCookie('chkWikibarSetEditorHeight');\n if(config.options['chkWikibarSetEditorHeight']){\n var rows = config.options['txtWikibarEditorRows'];\n if(!isNaN(rows)){ rows = 15; }\n var editor = param.button.editor;\n editor.rows = rows;\n config.options['txtWikibarEditorRows'] = rows;\n saveOptionCookie('txtWikibarEditorRows');\n }\n }\n };\n toolset.SEPERATOR = {};\n toolset.update = {\n CAPTION: 'check for updates',\n DISABLED: true,\n HANDLER: function(){}\n };\n return toolset;\n}\nfunction wikibar_genPaletteSelector(){\n try{\n var cpTiddlers = store.getTaggedTiddlers('ColorPalettes');\n if(!cpTiddlers) { return; }\n var palettes=[];\n palettes.push(wikibarColorTool.defaultPaletteName);\n for(var i=0; i<cpTiddlers.length; i++){\n palettes.push(cpTiddlers[i].title.trim());\n }\n var toolset={};\n for(i=0; i<palettes.length; i++){\n toolset[palettes[i]] = {\n TOOLTIP: palettes[i],\n SELECTED: (palettes[i]==wikibarColorTool.paletteName),\n HANDLER: wikibar_doSelectPalette\n };\n }\n return toolset;\n }catch(ex){ return null; }\n}\nfunction wikibar_onClickItem(e){\n if(!e){ e = window.event; }\n var theTarget = resolveTarget(e);\n if(theTarget.tagName=='INPUT'){\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n return;\n }\n var theButton = wikibar_resolveTargetButton(theTarget);\n if(!theButton){ return(false); }\n var o = theButton.toolItem;\n if(!o) { return; }\n var param = {\n event: e,\n button: theButton\n };\n if(o.HANDLER){ o.HANDLER(param); }\n if(o.DISABLED){\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n }\n return(false);\n}\nfunction wikibar_onClickMenuItem(e){\n if(!e){ e = window.event; }\n var theButton = wikibar_resolveTargetButton(resolveTarget(e));\n if(!theButton){ return(false); }\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n var title = theButton.tiddlerTitle;\n var editor = theButton.editor;\n var tool = theButton.toolItem;\n if(!tool) { return; }\n var popup = wikibarPopup.create(this);\n if(popup){\n wikibar_createMenu(popup,tool,title,editor);\n if(!popup.hasChildNodes()){\n wikibarPopup.remove();\n }else{\n wikibarPopup.show(popup, false);\n }\n }\n return(false);\n}\nvar wikibarColorTool = {\n defaultPaletteName : 'default',\n defaultColumns : 16,\n defaultPalette : [\n '#FFF','#DDD','#CCC','#BBB','#AAA','#999','#666','#333','#111','#000','#FC0','#F90','#F60','#F30','#C30','#C03',\n '#9C0','#9D0','#9E0','#E90','#D90','#C90','#FC3','#FC6','#F96','#F63','#600','#900','#C00','#F00','#F36','#F03',\n '#CF0','#CF3','#330','#660','#990','#CC0','#FF0','#C93','#C63','#300','#933','#C33','#F33','#C36','#F69','#F06',\n '#9F0','#CF6','#9C3','#663','#993','#CC3','#FF3','#960','#930','#633','#C66','#F66','#903','#C39','#F6C','#F09',\n '#6F0','#9F6','#6C3','#690','#996','#CC6','#FF6','#963','#630','#966','#F99','#F39','#C06','#906','#F3C','#F0C',\n '#3F0','#6F3','#390','#6C0','#9F3','#CC9','#FF9','#C96','#C60','#C99','#F9C','#C69','#936','#603','#C09','#303',\n '#0C0','#3C0','#360','#693','#9C6','#CF9','#FFC','#FC9','#F93','#FCC','#C9C','#969','#939','#909','#636','#606',\n '#060','#3C3','#6C6','#0F0','#3F3','#6F6','#9F9','#CFC','#9CF','#FCF','#F9F','#F6F','#F3F','#F0F','#C6C','#C3C',\n '#030','#363','#090','#393','#696','#9C9','#CFF','#39F','#69C','#CCF','#C9F','#96C','#639','#306','#90C','#C0C',\n '#0F3','#0C3','#063','#396','#6C9','#9FC','#9CC','#06C','#369','#99F','#99C','#93F','#60C','#609','#C3F','#C0F',\n '#0F6','#3F6','#093','#0C6','#3F9','#9FF','#699','#036','#039','#66F','#66C','#669','#309','#93C','#C6F','#90F',\n '#0F9','#6F9','#3C6','#096','#6FF','#6CC','#366','#069','#36C','#33F','#33C','#339','#336','#63C','#96F','#60F',\n '#0FC','#6FC','#3C9','#3FF','#3CC','#399','#033','#39C','#69F','#00F','#00C','#009','#006','#003','#63F','#30F',\n '#0C9','#3FC','#0FF','#0CC','#099','#066','#3CF','#6CF','#09C','#36F','#0CF','#09F','#06F','#03F','#03C','#30C'\n ],\n colorPicker : null,\n pickColorHandler: null,\n userData: null\n};\nwikibarColorTool.paletteName = wikibarColorTool.defaultPaletteName;\nwikibarColorTool.columns = wikibarColorTool.defaultColumns;\nwikibarColorTool.palette = wikibarColorTool.defaultPalette;\nwikibarColorTool.onPickColor = function(e){\n if (!e){ e = window.event; }\n var theCell = resolveTarget(e);\n if(!theCell){ return(false); }\n color = theCell.bgColor.toLowerCase();\n if(!color) { return; }\n wikibarColorTool.displayColorPicker(false);\n if(wikibarColorTool.pickColorHandler){\n wikibarColorTool.pickColorHandler(color, wikibarColorTool.userData);\n }\n return(false);\n};\nwikibarColorTool.onMouseOver = function(e){\n if (!e){ e = window.event; }\n var theButton = resolveTarget(e);\n if(!theButton){ return(false); }\n if(!wikibarColorTool) { return; }\n color = theButton.bgColor.toUpperCase();\n if(!color) { return; }\n td=document.getElementById('colorPickerInfo');\n if(!td) { return; }\n td.bgColor = color;\n td.innerHTML = '<span style=\s"color:#000;\s">'+color+'</span> ' +\n '<span style=\s"color:#fff;\s">'+color+'</span>';\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n return(false);\n};\nwikibarColorTool.openColorPicker = function(theTarget, pickColorHandler, userData){\n wikibarColorTool.skipClickDocumentEvent = true;\n wikibarColorTool.pickColorHandler = pickColorHandler;\n wikibarColorTool.userData = userData;\n wikibarColorTool.moveColorPicker(theTarget);\n};\nwikibarColorTool.convert3to6HexColor = function(c){\n c=c.trim();\n var rx=/^\s#(\sd|[a-f])(\sd|[a-f])(\sd|[a-f])$/gi;\n return (rx.test(c)? c.replace(rx, '#$1$1$2$2$3$3') : c);\n};\nwikibarColorTool.numToHexColor = function (n){\n if(typeof(n)=='number' && (n>=0 && n<=255)) {\n s = n.toString(16).toLowerCase();\n return ((s.length==1)? '0'+s : s);\n }else{\n return null;\n }\n};\nwikibarColorTool.renderColorPalette = function(){\n if(wikibarColorTool.paletteName==wikibarColorTool.defaultPaletteName){\n wikibarColorTool.palette=wikibarColorTool.defaultPalette;\n wikibarColorTool.columns=wikibarColorTool.defaultColumns;\n return;\n }\n tiddlerText = (store.getTiddlerText(wikibarColorTool.paletteName, '')).trim();\n if(tiddlerText.length<=0) { return; }\n var cpContents = tiddlerText.split('\sn');\n var colors=[];\n columns = wikibarColorTool.defaultColumns;\n var tmpArray=null;\n errCount=0;\n for(var i=0; i<cpContents.length; i++){\n cpLine=cpContents[i].trim();\n if( (!cpLine) || (cpLine.length<=0) || (cpLine.charAt(0) == '#') ){ continue; }\n if(cpLine.substring(0,8).toLowerCase()=='columns:'){\n tmpArray = cpLine.split(':');\n try{\n columns = parseInt(tmpArray[1],10);\n }catch(ex){\n columns = wikibarColorTool.defaultColumns;\n }\n }else{\n tmpArray = cpLine.replace('\st', ' ').split(/[ ]{1,}/);\n try{\n color='';\n for(var j=0; j<3; j++){\n c=parseInt(tmpArray[j].trim(), 10);\n if(isNaN(c)){\n break;\n }else{\n c=wikibarColorTool.numToHexColor(c);\n if(!c) {break;}\n color+=c;\n }\n }\n if(color.length==6){\n colors.push('#'+color);\n } else {\n throw 'error';\n }\n }catch(ex){\n }\n }\n }\n if(colors.length>0){\n wikibarColorTool.palette = colors;\n wikibarColorTool.columns = columns;\n }else{\n throw 'renderColorPalette(): No color defined in the palette.';\n }\n};\nwikibarColorTool.displayColorPicker = function(visible){\n if(wikibarColorTool.colorPicker){\n wikibarColorTool.colorPicker.style.display = (visible? 'block' : 'none');\n }\n};\nwikibarColorTool.moveColorPicker = function(theTarget){\n if(!wikibarColorTool.colorPicker){\n wikibarColorTool.createColorPicker();\n }\n var cp = wikibarColorTool.colorPicker;\n var rootLeft = findPosX(theTarget);\n var rootTop = findPosY(theTarget);\n var popupLeft = rootLeft;\n var popupTop = rootTop;\n var popupWidth = cp.offsetWidth;\n var winWidth = findWindowWidth();\n if(popupLeft + popupWidth > winWidth){\n popupLeft = winWidth - popupWidth;\n }\n cp.style.left = popupLeft + 'px';\n cp.style.top = popupTop + 'px';\n wikibarColorTool.displayColorPicker(true);\n};\nwikibarColorTool.createColorPicker = function(unused, palette){\n if(palette){ wikibarColorTool.paletteName=palette; }\n wikibarColorTool.renderColorPalette();\n wikibarColorTool.colorPicker = document.createElement('div');\n wikibarColorTool.colorPicker.id = 'colorPicker';\n document.body.appendChild(wikibarColorTool.colorPicker);\n var theTable = document.createElement('table');\n wikibarColorTool.colorPicker.appendChild(theTable);\n var theTR = document.createElement('tr');\n theTable.appendChild(theTR);\n var theTD = document.createElement('td');\n theTD.className = 'header';\n theTD.colSpan = wikibarColorTool.columns;\n theTD.innerHTML = wikibarColorTool.paletteName;\n theTR.appendChild(theTD);\n for(var i=0; i<wikibarColorTool.palette.length; i++){\n if((i%wikibarColorTool.columns)===0){\n theTR = document.createElement('tr');\n theTable.appendChild(theTR);\n }\n theTD = document.createElement('td');\n theTD.className = 'cell';\n theTD.bgColor = wikibarColorTool.convert3to6HexColor(wikibarColorTool.palette[i]);\n theTD.onclick = wikibarColorTool.onPickColor;\n theTD.onmouseover = wikibarColorTool.onMouseOver;\n theTR.appendChild(theTD);\n }\n rest = wikibarColorTool.palette.length % wikibarColorTool.columns;\n if(rest>0){\n theTD = document.createElement('td');\n theTD.colSpan = wikibarColorTool.columns-rest;\n theTD.bgColor = '#000000';\n theTR.appendChild(theTD);\n }\n theTR = document.createElement('tr');\n theTable.appendChild(theTR);\n theTD = document.createElement('td');\n theTD.colSpan = wikibarColorTool.columns;\n theTD.id = 'colorPickerInfo';\n theTR.appendChild(theTD);\n};\nwikibarColorTool.onDocumentClick = function(e){\n if (!e){ e = window.event; }\n if(wikibarColorTool.skipClickDocumentEvent) {\n wikibarColorTool.skipClickDocumentEvent = false;\n return true;\n }\n if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){\n wikibarColorTool.displayColorPicker(false);\n }\n return true;\n};\nfunction wikibar_doSelectPalette(param){\n clearMessage();\n var theButton = param.button;\n if(!theButton.toolItem.key) { return; }\n var palette = theButton.toolItem.key;\n var oldPaletteName = wikibarColorTool.paletteName;\n if(oldPaletteName != palette){\n try{\n wikibarColorTool.createColorPicker(theButton, palette);\n displayMessage('Palette \s"'+palette+'\s" ('+ wikibarColorTool.palette.length +' colors) is selected');\n }catch(ex){\n errMsg = ex;\n if(errMsg.substring(0,18)=='renderColorPalette'){\n displayMessage('Invalid palette \s"' + palette + '\s", please check it out!');\n wikibarColorTool.createColorPicker(theButton, oldPaletteName);\n }\n }\n }\n}\nvar wikibarPopup = {\n skipClickDocumentEvent: false,\n stack: []\n};\nwikibarPopup.resolveRootPopup = function(o){\n if(o.isOnMainMenu){ return null; }\n if(o.className.substring(0,12)=='wikibarPopup'){ return o;}\n return wikibarPopup.resolveRootPopup(o.parentNode);\n};\nwikibarPopup.create = function(root){\n for(var i=0; i<wikibarPopup.stack.length; i++){\n var p=wikibarPopup.stack[i];\n if(p.root==root){\n wikibarPopup.removeFrom(i+1);\n return null;\n }\n }\n var rootPopup = wikibarPopup.resolveRootPopup(root);\n if(!rootPopup){\n wikibarPopup.remove();\n }else{\n wikibarPopup.removeFromRootPopup(rootPopup);\n }\n var popup = createTiddlyElement(document.body,'div','wikibarPopup'+root.toolItem.key,'wikibarPopup');\n var pop = createTiddlyElement(popup,'table','','');\n wikibarPopup.stack.push({rootPopup: rootPopup, root: root, popup: popup});\n return pop;\n};\nwikibarPopup.show = function(unused,slowly){\n var curr = wikibarPopup.stack[wikibarPopup.stack.length-1];\n var overlayWidth = 1;\n var rootLeft, rootTop, rootWidth, rootHeight, popupLeft, popupTop, popupWidth;\n if(curr.rootPopup){\n rootLeft = findPosX(curr.rootPopup);\n rootTop = findPosY(curr.root);\n rootWidth = curr.rootPopup.offsetWidth;\n popupLeft = rootLeft + rootWidth - overlayWidth;\n popupTop = rootTop;\n }else{\n rootLeft = findPosX(curr.root);\n rootTop = findPosY(curr.root);\n rootHeight = curr.root.offsetHeight;\n popupLeft = rootLeft;\n popupTop = rootTop + rootHeight;\n }\n var winWidth = findWindowWidth();\n popupWidth = curr.popup.offsetWidth;\n if(popupLeft + popupWidth > winWidth){\n popupLeft = rootLeft - popupWidth + overlayWidth;\n }\n curr.popup.style.left = popupLeft + 'px';\n curr.popup.style.top = popupTop + 'px';\n curr.popup.style.display = 'block';\n addClass(curr.root, 'highlight');\n if(config.options.chkAnimate){\n anim.startAnimating(new Scroller(curr.popup,slowly));\n }else{\n window.scrollTo(0,ensureVisible(curr.popup));\n }\n};\nwikibarPopup.remove = function(){\n if(wikibarPopup.stack.length > 0){\n wikibarPopup.removeFrom(0);\n }\n};\nwikibarPopup.removeFrom = function(from){\n for(var t=wikibarPopup.stack.length-1; t>=from; t--){\n var p = wikibarPopup.stack[t];\n removeClass(p.root,'highlight');\n p.popup.parentNode.removeChild(p.popup);\n }\n wikibarPopup.stack = wikibarPopup.stack.slice(0,from);\n};\nwikibarPopup.removeFromRootPopup = function(from){\n for(var t=0; t<wikibarPopup.stack.length; t++){\n var p = wikibarPopup.stack[t];\n if(p.rootPopup==from){\n wikibarPopup.removeFrom(t);\n break;\n }\n }\n};\nwikibarPopup.onDocumentClick = function(e){\n if (!e){ e = window.event; }\n if(wikibarPopup.skipClickDocumentEvent){\n wikibarPopup.skipClickDocumentEvent=false;\n return true;\n }\n if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){\n wikibarPopup.remove();\n }\n return true;\n};\nvar wikibarStore = {\n TYPE: 'MAIN_MENU',\n help:{\n TYPE:'MENU',\n CAPTION: '<font face=\s"verdana\s">?</font>',\n TOOLTIP: 'about WikiBar',\n options:{\n TYPE:'MENU',\n DYNAITEM: wikibar_genWikibarOptions\n },\n about:{\n TYPE:'MENU',\n DYNAITEM: wikibar_genWikibarAbout\n }\n },\n preview:{\n TOOLTIP: 'preview this tiddler',\n CAPTION: '<font face=\s"verdana\s">∞</font>',\n HANDLER: wikibar_doPreview\n },\n line:{\n TOOLTIP: 'horizontal line',\n CAPTION: '<font face=\s"verdana\s">—</font>',\n syntax: '\sn----\sn',\n HANDLER: wikibar_editFormatByCursor\n },\n crlf:{\n TOOLTIP: 'new line',\n CAPTION: '<font face=\s"verdana\s">¶</font>',\n syntax: '\sn',\n HANDLER: wikibar_editFormatByCursor\n },\n selectAll:{\n TOOLTIP: 'select all',\n CAPTION: '<font face=\s"verdana\s">§</font>',\n HANDLER: wikibar_editSelectAll\n },\n deleteSelected:{\n TOOLTIP: 'delete selected',\n CAPTION: '<font face=\s"verdana\s">×</font>',\n syntax: '',\n HANDLER: wikibar_editFormat\n },\n textFormat:{\n TYPE: 'MENU',\n CAPTION: 'text',\n TOOLTIP: 'text formatters',\n ignore:{\n TOOLTIP: 'ignore wiki word',\n CAPTION: 'ignore wikiWord',\n syntax: '~user_text',\n hint: 'wiki_word',\n HANDLER: wikibar_editFormatByWord\n },\n bolder:{\n TOOLTIP: 'bolder text',\n CAPTION: '<strong>bolder</strong>',\n syntax: "''user_text''",\n hint: 'bold_text',\n HANDLER: wikibar_editFormatByWord\n },\n italic:{\n TOOLTIP: 'italic text',\n CAPTION: '<em>italic</em>',\n syntax: '\s/\s/user_text\s/\s/',\n hint: 'italic_text',\n HANDLER: wikibar_editFormatByWord\n },\n underline:{\n TOOLTIP: 'underline text',\n CAPTION: '<u>underline</u>',\n syntax: '__user_text__',\n hint: 'underline_text',\n HANDLER: wikibar_editFormatByWord\n },\n strikethrough:{\n TOOLTIP: 'strikethrough text',\n CAPTION: '<strike>strikethrough</strike>',\n syntax: '==user_text==',\n hint: 'strikethrough_text',\n HANDLER: wikibar_editFormatByWord\n },\n superscript:{\n TOOLTIP: 'superscript text',\n CAPTION: 'X<sup>superscript</sup>',\n syntax: '^^user_text^^',\n hint: 'superscript_text',\n HANDLER: wikibar_editFormatByWord\n },\n subscript:{\n TOOLTIP: 'subscript text',\n CAPTION: 'X<sub>subscript</sub>',\n syntax: '~~user_text~~',\n hint: 'subscript_text',\n HANDLER: wikibar_editFormatByWord\n },\n comment:{\n TOOLTIP: 'comment text',\n CAPTION: 'comment text',\n syntax: '/%user_text%/',\n hint: 'comment_text',\n HANDLER: wikibar_editFormatByWord\n },\n monospaced:{\n TOOLTIP: 'monospaced text',\n CAPTION: '<code>monospaced</code>',\n syntax: '{{{user_text}}}',\n hint: 'monospaced_text',\n HANDLER: wikibar_editFormatByWord\n }\n },\n paragraph:{\n TYPE: 'MENU',\n TOOLTIP: 'paragarph formatters',\n list:{\n TYPE: 'MENU',\n TOOLTIP: 'list tools',\n bullet:{\n TOOLTIP: 'bullet point',\n syntax: '*user_text',\n hint: 'bullet_text',\n HANDLER: wikibar_editFormatByLine\n },\n numbered:{\n TOOLTIP: 'numbered list',\n syntax: '#user_text',\n hint: 'numbered_text',\n HANDLER: wikibar_editFormatByLine\n }\n },\n heading:{\n TYPE: 'MENU',\n heading1:{\n CAPTION:'<h1>Heading 1</h1>',\n TOOLTIP: 'Heading 1',\n syntax: '!user_text',\n hint: 'heading_1',\n HANDLER: wikibar_editFormatByLine\n },\n heading2:{\n CAPTION:'<h2>Heading 2<h2>',\n TOOLTIP: 'Heading 2',\n syntax: '!!user_text',\n hint: 'heading_2',\n HANDLER: wikibar_editFormatByLine\n },\n heading3:{\n CAPTION:'<h3>Heading 3</h3>',\n TOOLTIP: 'Heading 3',\n syntax: '!!!user_text',\n hint: 'heading_3',\n HANDLER: wikibar_editFormatByLine\n },\n heading4:{\n CAPTION:'<h4>Heading 4</h4>',\n TOOLTIP: 'Heading 4',\n syntax: '!!!!user_text',\n hint: 'heading_4',\n HANDLER: wikibar_editFormatByLine\n },\n heading5:{\n CAPTION:'<h5>Heading 5</h5>',\n TOOLTIP: 'Heading 5',\n syntax: '!!!!!user_text',\n hint: 'heading_5',\n HANDLER: wikibar_editFormatByLine\n }\n },\n comment:{\n TYPE: 'MENU',\n commentByLine:{\n CAPTION:'comment by line',\n TOOLTIP: 'line comment',\n syntax: '/%user_text%/',\n hint: 'comment_text',\n HANDLER: wikibar_editFormatByLine\n },\n commentByBlock:{\n CAPTION:'comment by block',\n TOOLTIP: 'block comment',\n syntax: '/%\snuser_text\sn%/',\n hint: 'comment_text',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n monospaced:{\n TYPE: 'MENU',\n monosByLine:{\n CAPTION: 'monospaced by line',\n TOOLTIP: 'line monospaced',\n syntax: '{{{\snuser_text\sn}}}',\n hint: 'monospaced_text',\n HANDLER: wikibar_editFormatByLine\n },\n monosByBlock:{\n CAPTION: 'monospaced by block',\n TOOLTIP: 'block monospaced',\n syntax: '{{{\snuser_text\sn}}}',\n hint: 'monospaced_text',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n quote:{\n TYPE: 'MENU',\n quoteByLine:{\n CAPTION: 'quote by line',\n TOOLTIP: 'line quote',\n syntax: '>user_text',\n hint: 'quote_text',\n HANDLER: wikibar_editFormatByLine\n },\n quoteByBlcok:{\n CAPTION: 'quote by block',\n TOOLTIP: 'block quote',\n syntax: '<<<\snuser_text\sn<<<',\n hint: 'quote_text',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n plugin:{\n TYPE: 'MENU',\n code:{\n CAPTION: 'code area',\n TOOLTIP: 'block monospaced for plugin',\n syntax: '\sn\s/\s/{{{\snuser_text\sn\s/\s/}}}\sn',\n hint: 'monospaced_plugin_code',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n },\n commentByLine:{\n CAPTION: 'comment by line',\n TOOLTIP: 'line comment',\n syntax: '\s/\s/user_text',\n hint: 'plugin_comment',\n HANDLER: wikibar_editFormatByLine\n },\n commentByBlock:{\n CAPTION: 'comment by block',\n TOOLTIP: 'block comment',\n syntax: '\s/\s***\snuser_text\sn***\s/',\n hint: 'plugin_comment',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n css:{\n TYPE: 'MENU',\n code:{\n CAPTION: 'code area',\n TOOLTIP: 'block monospaced for css',\n syntax: '\sn\snuser_text\sn\sn',\n hint: 'monospaced_css_code',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n },\n commentByLine:{\n CAPTION: 'comment by line',\n TOOLTIP: 'line comment',\n syntax: '',\n hint: 'css_comment',\n HANDLER: wikibar_editFormatByLine\n },\n commentByBlock:{\n CAPTION: 'comment by block',\n TOOLTIP: 'block comment',\n syntax: '',\n hint: 'css_comment',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n }\n },\n color:{\n TYPE: 'MENU',\n TOOLTIP: 'color tools',\n highlight:{\n CAPTION:'highlight text',\n TOOLTIP: 'highlight text',\n syntax: '@@user_text@@',\n hint: 'highlight_text',\n HANDLER: wikibar_editFormatByWord\n },\n color:{\n CAPTION:'text color',\n TOOLTIP: 'text color',\n hint: 'your_text',\n syntax: '@@color(%1):user_text@@',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByWord\n },\n bgcolor:{\n CAPTION:'background color',\n TOOLTIP: 'background color',\n hint: 'your_text',\n syntax: '@@bgcolor(%1):user_text@@',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByWord\n },\n colorcode:{\n CAPTION:'color code',\n TOOLTIP: 'insert color code',\n syntax: '%1',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByCursor\n },\n 'color palette':{\n TYPE:'MENU',\n DYNAITEM: wikibar_genPaletteSelector,\n SEPERATOR:{},\n morePalette:{\n CAPTION:'more palettes',\n TOOLTIP:'get more palettes',\n HANDLER: wikibar_getMorePalette\n }\n }\n },\n link:{\n TYPE: 'MENU',\n TOOLTIP: 'insert link',\n wiki:{\n CAPTION:'wiki link',\n TOOLTIP: 'wiki link',\n syntax: '[[user_text]]',\n hint: 'wiki_word',\n HANDLER: wikibar_editFormatByWord\n },\n pretty:{\n CAPTION: 'pretty link',\n TOOLTIP: 'pretty link',\n syntax: '[[user_text|%1]]',\n hint: 'pretty_word',\n param: 'PrettyLink Target',\n HANDLER: wikibar_getLinkUrl,\n doMore: wikibar_editFormatByWord\n },\n url:{\n TOOLTIP: 'url link',\n syntax: '[[user_text|%1]]',\n hint: 'your_text',\n param: 'http:\s/\s/...',\n HANDLER: wikibar_getLinkUrl,\n doMore: wikibar_editFormatByWord\n },\n image:{\n TOOLTIP: 'image link',\n syntax: '[img[user_text|%1]]',\n hint: 'alt_text',\n param: 'image/icon.jpg',\n HANDLER: wikibar_getLinkUrl,\n doMore: wikibar_editFormatByWord\n }\n },\n macro:{},\n more:{\n TYPE: 'MENU',\n TOOLTIP: 'more tools',\n table:{\n TYPE: 'MENU',\n TOOLTIP: 'table',\n table:{\n CAPTION:'create table',\n TOOLTIP: 'create a new table',\n syntax: '\sn%1\sn',\n HANDLER: wikibar_getTableRowCol,\n doMore: wikibar_editFormatByWord\n },\n header:{\n TOOLTIP: 'table header text',\n syntax: '|user_text|c',\n hint: 'table_header',\n HANDLER: wikibar_editFormatByWord\n },\n cell:{\n TOOLTIP: 'create a tabel cell',\n syntax: '|user_text|',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByWord\n },\n columnHeader:{\n CAPTION:'column header',\n TOOLTIP: 'create a column header cell',\n syntax: '|!user_text|',\n hint: 'column_header',\n HANDLER: wikibar_editFormatByWord\n },\n cell:{\n TYPE: 'MENU',\n CAPTION: 'cell options',\n bgcolor:{\n CAPTION: 'background color',\n TOOLTIP: 'cell bgcolor',\n syntax: '|bgcolor(%1):user_text|',\n hint: 'your_text',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByTableCell\n },\n alignLeft:{\n CAPTION: 'align left',\n TOOLTIP: 'left align cell text',\n syntax: '|user_text|',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByTableCell\n },\n alignCenter:{\n CAPTION: 'align center',\n TOOLTIP: 'center align cell text',\n syntax: '| user_text |',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByTableCell\n },\n alignRight:{\n CAPTION: 'align right',\n TOOLTIP: 'right align cell text',\n syntax: '| user_text|',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByTableCell\n }\n }\n },\n html:{\n TYPE: 'MENU',\n html:{\n CAPTION: '<html>',\n TOOLTIP: 'html tag',\n syntax: '<html>\snuser_text\sn</html>',\n hint: 'html_content',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n }\n },\n addon:{\n TYPE: 'MENU',\n TOOLTIP:'3rd party tools',\n 'about addons':{\n TOOLTIP: 'list loaded addons',\n HANDLER: wikibar_doListAddons\n },\n SEPERATOR:{}\n }\n};\naddEvent(document, 'click', wikibarColorTool.onDocumentClick);\naddEvent(document, 'click', wikibarPopup.onDocumentClick);\nwikibar_install();\n//}}}\n\n\n
http://tiddlyvault.tiddlyspot.com/\nhttp://www.tiddlywiki.com/\nhttp://cctiddly.sourceforge.net/
RiftRoamers CoLab
Ein kollaboratives Projekt zur Weiterentwicklung einiger RiftRoamers Aspekte\n
RiftRoamers\n[[News]] - <<tag ToDo>>\n\n<<tag TechSociety>>\n<<tag InfoScience>>\n<<tag BrainPower>>\n<<tag ThinkingNets>>\n<<tag AccessControl>>\n<<tag AlienIntelligence>>\n\n<<tag GameAspect>>\n<<tag RoamersRule>>\n\n[[Guidelines]]\nEditorsDiscussion\nChangeLog\n\n[[WelcomeToTiddlyspot]]\nGettingStarted
[[News]]\nToDo
//============================================================================\n//============================================================================\n// FormTiddlerPlugin\n//============================================================================\n//============================================================================\n\nif (!window.abego) window.abego = {};\n\nabego.getOptionsValue = function(element,i) {\n var v = element.options[i].value;\n if (!v && element.options[i].text)\n v = element.options[i].text;\n return v;\n};\n\nversion.extensions.FormTiddlerPlugin = {\n major: 1, minor: 0, revision: 5,\n date: new Date(2006, 2, 24), \n type: 'plugin',\n source: "http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"\n};\n\n// For backward compatibility with v1.2.x\n//\nif (!window.story) window.story=window; \nif (!TiddlyWiki.prototype.getTiddler) TiddlyWiki.prototype.getTiddler = function(title) { return t = this.tiddlers[title]; return (t != undefined && t instanceof Tiddler) ? t : null; } \n\n//============================================================================\n// formTiddler Macro\n//============================================================================\n\n// -------------------------------------------------------------------------------\n// Configurations and constants \n// -------------------------------------------------------------------------------\n\nconfig.macros.formTiddler = {\n // Standard Properties\n label: "formTiddler",\n version: {major: 1, minor: 0, revision: 4, date: new Date(2006, 2, 7)},\n prompt: "Edit tiddler data using forms",\n\n // Define the "setters" that set the values of INPUT elements of a given type\n // (must match the corresponding "getter")\n setter: { \n button: function(e, value) {/*contains no data */ },\n checkbox: function(e, value) {e.checked = value;},\n file: function(e, value) {try {e.value = value;} catch(e) {/* ignore, possibly security error*/}},\n hidden: function(e, value) {e.value = value;},\n password: function(e, value) {e.value = value;},\n radio: function(e, value) {e.checked = (e.value == value);},\n reset: function(e, value) {/*contains no data */ },\n "select-one": function(e, value) {config.macros.formTiddler.setSelectOneValue(e,value);},\n "select-multiple": function(e, value) {config.macros.formTiddler.setSelectMultipleValue(e,value);},\n submit: function(e, value) {/*contains no data */},\n text: function(e, value) {e.value = value;},\n textarea: function(e, value) {e.value = value;}\n },\n\n // Define the "getters" that return the value of INPUT elements of a given type\n // Return undefined to not store any data.\n getter: { \n button: function(e, value) {return undefined;},\n checkbox: function(e, value) {return e.checked;},\n file: function(e, value) {return e.value;},\n hidden: function(e, value) {return e.value;},\n password: function(e, value) {return e.value;},\n radio: function(e, value) {return e.checked ? e.value : undefined;},\n reset: function(e, value) {return undefined;},\n "select-one": function(e, value) {return config.macros.formTiddler.getSelectOneValue(e);},\n "select-multiple": function(e, value) {return config.macros.formTiddler.getSelectMultipleValue(e);},\n submit: function(e, value) {return undefined;},\n text: function(e, value) {return e.value;},\n textarea: function(e, value) {return e.value;}\n }\n};\n\n\n// -------------------------------------------------------------------------------\n// The formTiddler Macro Handler \n// -------------------------------------------------------------------------------\n\nconfig.macros.formTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n if (!config.macros.formTiddler.checkForExtensions(place, macroName)) {\n return;\n }\n // --- Parsing ------------------------------------------\n\n var i = 0; // index running over the params\n\n // get the name of the form template tiddler\n var formTemplateName = undefined;\n if (i < params.length) {\n formTemplateName = params[i];\n i++;\n }\n\n if (!formTemplateName) {\n config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");\n return;\n }\n\n\n // --- Processing ------------------------------------------\n\n // Get the form template text. \n // (This contains the INPUT elements for the form.)\n var formTemplateTiddler = store.getTiddler(formTemplateName);\n if (!formTemplateTiddler) {\n config.macros.formTiddler.createErrorElement(place, "Form template '" + formTemplateName + "' not found.");\n return;\n }\n var templateText = formTemplateTiddler.text;\n if(!templateText) {\n // Shortcut: when template text is empty we do nothing.\n return;\n }\n\n // Get the name of the tiddler containing this "formTiddler" macro\n // (i.e. the tiddler, that will be edited and that contains the data)\n var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);\n\n // Append a "form" element. \n var formName = "form"+formTemplateName+"__"+tiddlerName;\n var e = document.createElement("form");\n e.setAttribute("name", formName);\n place.appendChild(e);\n\n // "Embed" the elements defined by the templateText (i.e. the INPUT elements) \n // into the "form" element we just created\n wikify(templateText, e);\n\n // Initialize the INPUT elements.\n config.macros.formTiddler.initValuesAndHandlersInFormElements(formName, DataTiddler.getDataObject(tiddlerName));\n}\n\n\n// -------------------------------------------------------------------------------\n// Form Data Access \n// -------------------------------------------------------------------------------\n\n// Internal.\n//\n// Initialize the INPUT elements of the form with the values of their "matching"\n// data fields in the tiddler. Also setup the onChange handler to ensure that\n// changes in the INPUT elements are stored in the tiddler's data.\n//\nconfig.macros.formTiddler.initValuesAndHandlersInFormElements = function(formName, data) {\n // config.macros.formTiddler.trace("initValuesAndHandlersInFormElements(formName="+formName+", data="+data+")");\n\n // find the form\n var form = config.macros.formTiddler.findForm(formName);\n if (!form) {\n return;\n }\n\n try {\n var elems = form.elements;\n for (var i = 0; i < elems.length; i++) {\n var c = elems[i];\n \n var setter = config.macros.formTiddler.setter[c.type];\n if (setter) {\n var value = data[c.name];\n if (value != null) {\n setter(c, value);\n }\n c.onchange = onFormTiddlerChange;\n } else {\n config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+c.type+"'. (Element '"+c.name+"' in form '"+formName+"')");\n }\n }\n } catch(e) {\n config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+e);\n }\n}\n\n\n// Internal.\n//\n// @return [may be null]\n//\nconfig.macros.formTiddler.findForm = function(formName) {\n // We must manually iterate through the document's forms, since\n // IE does not support the "document[formName]" approach\n\n var forms = window.document.forms;\n for (var i = 0; i < forms.length; i++) {\n var form = forms[i];\n if (form.name == formName) {\n return form;\n }\n }\n\n return null;\n}\n\n\n// Internal.\n//\nconfig.macros.formTiddler.setSelectOneValue = function(element,value) {\n var n = element.options.length;\n for (var i = 0; i < n; i++) {\n element.options[i].selected = abego.getOptionsValue(element,i) == value;\n }\n}\n\n// Internal.\n//\nconfig.macros.formTiddler.setSelectMultipleValue = function(element,value) {\n var values = {};\n for (var i = 0; i < value.length; i++) {\n values[value[i]] = true;\n }\n \n var n = element.length;\n for (var i = 0; i < n; i++) {\n element.options[i].selected = !(!values[abego.getOptionsValue(element,i)]);\n }\n}\n\n// Internal.\n//\nconfig.macros.formTiddler.getSelectOneValue = function(element) {\n var i = element.selectedIndex;\n return (i >= 0) ? abego.getOptionsValue(element,i) : null;\n}\n\n// Internal.\n//\nconfig.macros.formTiddler.getSelectMultipleValue = function(element) {\n var values = [];\n var n = element.length;\n for (var i = 0; i < n; i++) {\n if (element.options[i].selected) {\n values.push(abego.getOptionsValue(element,i));\n }\n }\n return values;\n}\n\n\n\n// -------------------------------------------------------------------------------\n// Helpers \n// -------------------------------------------------------------------------------\n\n// Internal.\n//\nconfig.macros.formTiddler.checkForExtensions = function(place,macroName) {\n if (!version.extensions.DataTiddlerPlugin) {\n config.macros.formTiddler.createErrorElement(place, "<<" + macroName + ">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");\n return false;\n }\n return true;\n}\n\n// Internal.\n//\n// Displays a trace message in the "TiddlyWiki" message pane.\n// (used for debugging)\n//\nconfig.macros.formTiddler.trace = function(s) {\n displayMessage("Trace: "+s);\n}\n\n// Internal.\n//\n// Display some error message in the "TiddlyWiki" message pane.\n//\nconfig.macros.formTiddler.displayFormTiddlerError = function(s) {\n alert("FormTiddlerPlugin Error: "+s);\n}\n\n// Internal.\n//\n// Creates an element that holds an error message\n// \nconfig.macros.formTiddler.createErrorElement = function(place, message) {\n return createTiddlyElement(place,"span",null,"formTiddlerError",message);\n}\n\n// Internal.\n//\n// Returns the name of the tiddler containing the given element.\n// \nconfig.macros.formTiddler.getContainingTiddlerName = function(element) {\n return story.findContainingTiddler(element).id.substr(7);\n}\n\n// -------------------------------------------------------------------------------\n// Event Handlers \n// -------------------------------------------------------------------------------\n\n// This function must be called by the INPUT elements whenever their\n// data changes. Typically this is done through an "onChange" handler.\n//\nfunction onFormTiddlerChange (e) {\n // config.macros.formTiddler.trace("onFormTiddlerChange "+e);\n\n if (!e) var e = window.event;\n\n var target = resolveTarget(e);\n var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(target);\n var getter = config.macros.formTiddler.getter[target.type];\n if (getter) {\n var value = getter(target);\n DataTiddler.setData(tiddlerName, target.name, value);\n } else {\n config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+target.type+"'. (Element '"+target.name+"' used in tiddler '"+tiddlerName+"')");\n }\n}\n\n// ensure that the function can be used in HTML event handler\nwindow.onFormTiddlerChange = onFormTiddlerChange;\n\n\n// -------------------------------------------------------------------------------\n// Stylesheet Extensions (may be overridden by local StyleSheet)\n// -------------------------------------------------------------------------------\n\nsetStylesheet(\n ".formTiddlerError{color: #ffffff;background-color: #880000;}",\n "formTiddler");\n\n\n//============================================================================\n// checkForDataTiddlerPlugin Macro\n//============================================================================\n\nconfig.macros.checkForDataTiddlerPlugin = {\n // Standard Properties\n label: "checkForDataTiddlerPlugin",\n version: {major: 1, minor: 0, revision: 0, date: new Date(2005, 12, 14)},\n prompt: "Check if the DataTiddlerPlugin exists"\n}\n\nconfig.macros.checkForDataTiddlerPlugin.handler = function(place,macroName,params) {\n config.macros.formTiddler.checkForExtensions(place, config.macros.formTiddler.label);\n}\n\n\n\n//============================================================================\n// newTiddlerWithForm Macro\n//============================================================================\n\nconfig.macros.newTiddlerWithForm = {\n // Standard Properties\n label: "newTiddlerWithForm",\n version: {major: 1, minor: 0, revision: 1, date: new Date(2006, 1, 6)},\n prompt: "Creates a new Tiddler with a <<formTiddler ...>> macro"\n}\n\nconfig.macros.newTiddlerWithForm.handler = function(place,macroName,params) {\n // --- Parsing ------------------------------------------\n\n var i = 0; // index running over the params\n\n // get the name of the form template tiddler\n var formTemplateName = undefined;\n if (i < params.length) {\n formTemplateName = params[i];\n i++;\n }\n\n if (!formTemplateName) {\n config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");\n return;\n }\n\n // get the button label\n var buttonLabel = undefined;\n if (i < params.length) {\n buttonLabel = params[i];\n i++;\n }\n\n if (!buttonLabel) {\n config.macros.formTiddler.createErrorElement(place, "No button label specified in <<" + macroName + ">>.");\n return;\n }\n\n // get the (optional) tiddlerName script and "askUser"\n var tiddlerNameScript = undefined;\n var askUser = false;\n if (i < params.length) {\n tiddlerNameScript = params[i];\n i++;\n\n if (i < params.length && params[i] == "askUser") {\n askUser = true;\n i++;\n }\n }\n\n // --- Processing ------------------------------------------\n\n if(!readOnly) {\n var onClick = function() {\n var tiddlerName;\n if (tiddlerNameScript) {\n try {\n tiddlerName = eval(tiddlerNameScript);\n } catch (ex) {\n }\n }\n if (!tiddlerName || askUser) {\n tiddlerName = prompt("Please specify a tiddler name.", askUser ? tiddlerName : "");\n }\n while (tiddlerName && store.getTiddler(tiddlerName)) {\n tiddlerName = prompt("A tiddler named '"+tiddlerName+"' already exists.\sn\sn"+"Please specify a tiddler name.", tiddlerName);\n }\n\n // tiddlerName is either null (user canceled) or a name that is not yet in the store.\n if (tiddlerName) {\n var body = "<<formTiddler [["+formTemplateName+"]]>>";\n var tags = [];\n store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);\n story.displayTiddler(null,tiddlerName,1);\n }\n }\n\n createTiddlyButton(place,buttonLabel,buttonLabel,onClick);\n }\n}
|''Type:''|file|\n|''URL:''|http://tiddly.riftroamers.net/riftroamers.html|\n|''Workspace:''|(default)|\n\nThis tiddler was automatically created to record the details of this server
2007-12-28: \n- ~TiddlyWiki bei Tiddlyspot.comaufgesetzt\n- Basiseinstellungen und Menü erstellt\n- Einige Tiddlers/Artikel bzw. Testseiten eingerichtet: \n -- RiftRoamers\n -- CoLab\n -- [[News]]\n -- [[Guidelines]]\n -- ChangeLog\n -- Beitrag 1: Technologie und Gesellschaft (später von MiB in TechSociety umgewandelt)\n -- Online-Version\n -- Online-Änderungen\n -- Offline-Version\n -- Offline-Änderungen\n -- Master-Version\n- Kleinigkeiten konfiguriert: Upload Passwort, Editor Username, etc.\n\n2008-01-02:\n- Mögliche Themenfelder als Tags ins Menu integriert\n- Nutzung von CoLab als Tag.\n- [[Guidelines]] ergänzt.
CoLab = Cooperative Laboratory, in diesem Fall zudem eine Anspielung auf kollaborative Tätigkeiten, also gemeisames Arbeiten.\n\nTag für alle Seiten, die eben diesen gemeinsame Arbeiten oder das Wiki als solches zum Thema haben.
Ein Tiddler für den Austausch von Vorschlägen und Meinungen zum CoLab und seiner Beiträge.\n* Themenfelder im Hauptmenü erscheinen mir gut, aber das //Beitrag X// würde ich loswerden. Was da sehr gut funktioniert ist der direkte Einsatz von Tags, die über ein spezielles Kommando auch dort so funktionieren, wie im Tags Menu rechts. (Siehe Beispiel ToDo) So kann auch ein Hauptbeitrag existieren (der Tag Tiddler), muss aber nicht. In beiden Fällen können wir Beiträge zu Themenfeldern gruppieren - und sind dabei noch nicht einmal auf eine Hierarchie eingeschränkt.\n* Die Mischung Englisch - Deutsch lässt mich natürlich stolpern. Ich nehme an, die RiftRoamers Texte sind in deutsch?\n\nHi MiB\n* Bzgl. //Beitrag X// stimme ich Dir zu. Die Tag Geschichte gefällt mir wirklich gut. Habe ich mir noch nicht angesehen.\n* Das stimmt, die RiftRoamers Texte sind bisher komplett in deutsch verfaßt. \n* Die Mischung Deutsch English hat keine besondere Bewandnis, hier sollten wir nehmen was uns am besten paßt.\n* Bezgl. Bereitstellung des ~TiddlyWiki auf dem eigenen Server habe ich mich noch nicht angestrengt. Kommt aber noch...
A pure tag that collects tiddlers which describe roleplaying aspects.\nConcerned with concepts that apply to any ~SciFi RPG and thus fully independent of RiftRoamers rules, which are tagged RoamersRule.
Die Guidelines stellen einen Leitfaden zur organisation der Informationen auf dieser Webseite.\nDieser Leitfaden sollte unser erstes Projekt sein, damit wir die seite einigermaßen strukturiert ergänzen können.\nEvtl. macht es zudem Sinn eine Art Protokolldatei zu pflegen in der wir chronologisch unsere Änderungen stichpunktartig festhalten.\n\n__Für die tägliche Arbeit__\nDiese Optionen finden sich rechts im Menü:\nClose all - Schließt alle geöffneten Tiddlers (Artikel)\n- Permaview - Erzeugt eine URL die alle angezeigten Elemente abruft.\n- New Tiddler - Erzeugt einen neuen Tiddler (Artikel)\n- New Journal - Erzeugt einen neuen Tiddler des Aktuellen Zeitstempels\n- Save Changes - Speichert das aktuelle ~TiddlyWiki bei Offline-Änderungen\n- Save to Web - Speichert das aktuelle ~TiddlyWiki bei Online-Änderungen (Login)\n- Download - Läd die online gespeichert Version als Offlinekopie herunter\n-- Offlinekopie herunterladen: [[Download|http://riftroamers.tiddlyspot.com/download]]\n\nOptions enthält z.B. das Upload Password um "Save to web" nutzen zu können\n\n__Import des Offline ~TiddlyWiki in das Online ~TiddlyWiki__\n\n__Tagging__\nEine der Stärken des ~TiddlyWiki ist das Tagging, welches zB auch von ~GMail eingesetzt wird um einen Hierarchie-unabhängigen Zugriff aufzubauen.\nEin Tag kann eine eigene Seite haben, muss aber nicht. Wenn sie existiert sollte eine derartige Seite die Inhalte definieren und einen Überblick geben.\nJede Seite, die den Tag dann nutzt, trägt zu diesem Thema etwas bei. Dabei sind mehrere Tags für eine Seite natürlich möglich - und nützlich.\nEs ist nicht der schlechteste Ansatz generell //jede// Seite mit einem Tag zu versehen.\n\n__Wiki Word__\nVorsicht bei Wörtern, die einen zweiten Großbuchstaben beinhalten - und dass kann nach einem Bindestrich sein. Derartige Wörter werden als Wiki Word erkannt, und so als fehlender Tiddler gelistet, was, sofern nicht beabsichtigt, unpraktisch - und, schlimmer noch, unästhetisch - ist. Unterdrücken tut man dergleichen mit einer vorangestellten Tilde.
/***\n|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|\n|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |\n|''Version:''|1.1.0|\n|''Date:''|mar 17, 2007|\n|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#[[BSD open source license]] ]]|\n|''~CoreVersion:''|2.2.0|\n***/\n//{{{\nversion.extensions.LoadRemoteFileThroughProxy = {\n major: 1, minor: 1, revision: 0, \n date: new Date("mar 17, 2007"), \n source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};\n\nif (!window.bidix) window.bidix = {}; // bidix namespace\nif (!bidix.core) bidix.core = {};\n\nbidix.core.loadRemoteFile = loadRemoteFile;\nloadRemoteFile = function(url,callback,params)\n{\n if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ \n url = store.getTiddlerText("SiteProxy", "/proxy/") + url;\n }\n return bidix.core.loadRemoteFile(url,callback,params);\n}\n//}}}\n
Diese Version sollte immer aktuell gehalten werden und als Basis für eigenen Änderungen gelten. Ob das so funktioniert ist noch nicht getestet.
Even though I like to wear dark colors, I hate white shirts.\nSo, obviously, I am no Man in Black.\n\nOn the other hand, it is a nice abbreviation. \nIf you do not know //what for//, you probably should not access this wiki.
Freitag 28.12.07\nRiftRoamers CoLab ist online. Testweise. Mal schauen ob es für uns so passt.
Diese Version befindet sich auf dem eigenen Computer. Ob aktuell oder nicht... ;-)
Damit sind arbeiten an dieser Webseite gemeint, die an eine ~TiddlyWiki-Kopie auf dem eigenen Rechner bearbeitet werden.\n\nDamit diese Offline-Änderungen in der Online-Version sichtbar werden, ist es notwendig die Offline-Version mit der Online-Version zu synchronisieren, bzw. die Inhalte in die Online-Version zu importieren.
Die unter http://riftroamers.tiddlyspot.com/ erreichbare Version unseres ~TiddlyWiki.
Damit sind Arbeiten an dieser Webseite gemeint die - nach einem Login unter http://riftroamers.tiddlyspot.com - online erfolgen.\nDie Online-Version gilt aktuell als Master-Version. Durch einen [[Download|http://riftroamers.tiddlyspot.com/download]] erhält man eine Offline-Version.\n\nÜber die Versionspflege müssen wir uns jedoch noch ein paar Gedanken machen.\n\nAuch wäre ein hosting auf dem eigenen Webserver wichtig. Aber zum Testen sollte diese erst einmal gehen.
Type the text for 'RiftMaster'
Die Gesellschaft des Jahres 3030 AD zeichnet ein fremdes und unheilvolles Bild von der menschlichen Existenz. Amok gelaufene biotechnologische Experimente, durch den Cyberspace marodierende ~AIs, die Neuentwicklung von Stadtstaaten inmitten der interstellaren Bündnisse und aus den unbekannten Weiten des Universums auftauchende und vermehrt feindliche Fremdrassen schaffen eine Aura der unterschwelligen Angst in der Bevölkerung, die sich in verzweifelter Resignation ob der Realität und in gewaltvollen offenen Aufständen der minderbemittelten Masse äußert.\n\nPolizeistaaten sind vorherrschend, ein Zeugnis politischer Unfähigkeit. Aberglaube herrscht über technologische Errungenschaften. Der Glaube an höhere Wesen, die Götter, gewinnt wieder an Einfluss. Die Mehrheit der Menschen verkriecht sich im Untergrund, ist Teil einer geistlichen oder politischen Bewegung, gehört einer militärischen Einheit an oder zieht mit rebellierenden Nomadenpacks umher, die das Land fernab der Zivilisation bewohnen.\n\nUnter dem Mantel der Einigkeit und politischen Korrektheit brodelt ein Feuer, dessen Nahrung die Erblast einer längst überwundenen Unterdrückung der gesamten Menschheit durch eine feindliche Fremdrasse, die Morlorn, ist und deren Narben sie noch heute im Antlitz ihrer Existenz trägt.\n\nEs ist ein Feuer der Furcht vor dem unbekannten Bösen unter den Sternen, der Erscheinung einer Prophezeiung, deren Inhalte in jeder bekannten Religion erwähnt werden, deren Ursprung selbst den seit Jahrtausenden etablierten nicht menschlichen Zivilisationen ein Rätsel ist und deren ultimative Aussage die Vernichtung allen zivilisierten Lebens ist.\n\nEs ist ein Feuer der Ruhelosigkeit, denn der Mensch ist nach dem Verlust seiner Wiege, der Erde, ein rastloses Volk geworden, ständig und unter allen Umständen jederzeit bereit sich seinen Platz im Universum zu schaffen, um eines Tages wieder zurückkehren zu können an den Ort, der ihn einst geschaffen hatte.\n\nEs ist ein Feuer der Verbissenheit, ob des Kampfes der noch immer tobt im Sol System, dessen dritter Planet von den Morlorn verbrannt, ausgebeutet und terraformiert wurde, dessen Atmosphären jetzt dem Menschen gegenüber so feindlich ist, wie sie es nur sein kann und dessen Eroberer ihn noch immer mit ihrer machtvollen Kriegsmaschinerie besetzen. Hartnäckig und seit vierhundert Jahren mit unverminderter Macht.\n\nEs ist ein Feuer der Hoffnung in den Herzen derer, die sich nicht von der überall umgreifenden Resignation leiten lassen, sondern auf eigene Initiative den Kampf gegen das Unheil dieser Tage aufgenommen haben und im Untergrund, auf der Schneide zwischen Legalität und Verbrechen oder in den höchsten Positionen politischer, wirtschaftlicher oder moralischer Macht Seite an Seite mit Gleichgesinnten versuchen ein besseres Leben zu leben.\n\nEs ist die hässliche Fratze einer Cyberpunk Vision, die die Gesellschaft auf die Gesichter der Menschen zeichnet, deren Sprung zu den Sternen nicht die allgegenwärtige Präsenz eines "high tech, low life"-Lebensstandards und die Müllhalden der elitären Wohlstandsgesellschaft hatte abstreifen können.\n\nEs ist unsere Zukunft, die sich vor Schmerzen krümmend vor unseren Füßen ausbreitet und mit jedem zuckenden Atemzug darum bettelt durch Gerechtigkeit und Frieden von ihren Qualen erlöst zu werden. Ist dies unsere Zukunft?\n\nEs ist auch eine Zeit voller technischer Wunder, voller faszinierender Kulturen und voller Chancen. Doch scheint es, das niemand diese so richtig wahrzunehmen vermag.\n\n\n
A pure tag that collects tiddlers which describe specific RiftRoamers gameplay rules.\nProbably of interest to the RiftMaster, but not to MiB, who thinks more within the concepts tagged GameAspect.
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 28/12/2007 10:38:02 | RiftMaster | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . |\n| 28/12/2007 11:06:22 | RiftMaster | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . | ok |\n| 28/12/2007 11:07:13 | RiftMaster | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . |\n| 28/12/2007 11:38:37 | RiftMaster | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . |\n| 28/12/2007 13:41:25 | MiB | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . |\n| 31/12/2007 15:09:06 | YourName | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . | ok |\n| 31/12/2007 15:36:44 | YourName | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . |\n| 02/01/2008 04:14:54 | MiB | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . |\n| 02/01/2008 04:15:29 | MiB | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . |\n| 02/01/2008 04:15:42 | MiB | [[/|http://riftroamers.tiddlyspot.com/]] | [[store.cgi|http://riftroamers.tiddlyspot.com/store.cgi]] | . | [[index.html | http://riftroamers.tiddlyspot.com/index.html]] | . | ok |
/***\nContains the stuff you need to use Tiddlyspot\nNote you must also have UploadPlugin installed\n***/\n//{{{\n\n// edit this if you are migrating sites or retrofitting an existing TW\nconfig.tiddlyspotSiteId = 'riftroamers';\n\n// make it so you can by default see edit controls via http\nconfig.options.chkHttpReadOnly = false;\nwindow.readOnly = false; // make sure of it (for tw 2.2)\n\n// disable autosave in d3\nif (window.location.protocol != "file:")\n config.options.chkGTDLazyAutoSave = false;\n\n// tweak shadow tiddlers to add upload button, password entry box etc\nwith (config.shadowTiddlers) {\n SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';\n SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");\n OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");\n DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");\n MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");\n}\n\n// create some shadow tiddler content\nmerge(config.shadowTiddlers,{\n\n'WelcomeToTiddlyspot':[\n "This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",\n "<<tiddler TspotControls>>",\n "See also GettingStarted.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \s"save to web\s" button in the column on the right.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \s"upload\s" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."\n].join("\sn"),\n\n'TspotControls':[\n "| tiddlyspot password:|<<option pasUploadPassword>>|",\n "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<<br>>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",\n "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[announcements|http://announce.tiddlyspot.com/]], [[blog|http://tiddlyspot.com/blog/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"\n].join("\sn"),\n\n'TspotSidebar':[\n "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"\n].join("\sn"),\n\n'TspotOptions':[\n "tiddlyspot password:",\n "<<option pasUploadPassword>>",\n ""\n].join("\sn")\n\n});\n//}}}\n
/***\n|''Name:''|PasswordOptionPlugin|\n|''Description:''|Extends ~TiddlyWiki options with non encrypted password option.|\n|''Version:''|1.0.2|\n|''Date:''|Apr 19, 2007|\n|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#[[BSD open source license]] ]]|\n|''~CoreVersion:''|2.2.0 (Beta 5)|\n***/\n//{{{\nversion.extensions.PasswordOptionPlugin = {\n major: 1, minor: 0, revision: 2, \n date: new Date("Apr 19, 2007"),\n source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',\n author: 'BidiX (BidiX (at) bidix (dot) info',\n license: '[[BSD open source license|http://tiddlywiki.bidix.info/#[[BSD open source license]]]]',\n coreVersion: '2.2.0 (Beta 5)'\n};\n\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordInputType = "password"; // password | text\nsetStylesheet(".pasOptionInput {width: 11em;}\sn","passwordInputTypeStyle");\n\nmerge(config.macros.option.types, {\n 'pas': {\n elementType: "input",\n valueField: "value",\n eventName: "onkeyup",\n className: "pasOptionInput",\n typeValue: config.macros.option.passwordInputType,\n create: function(place,type,opt,className,desc) {\n // password field\n config.macros.option.genericCreate(place,'pas',opt,className,desc);\n // checkbox linked with this password "save this password on this computer"\n config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc); \n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n },\n onChange: config.macros.option.genericOnChange\n }\n});\n\nmerge(config.optionHandlers['chk'], {\n get: function(name) {\n // is there an option linked with this chk ?\n var opt = name.substr(3);\n if (config.options[opt]) \n saveOptionCookie(opt);\n return config.options[name] ? "true" : "false";\n }\n});\n\nmerge(config.optionHandlers, {\n 'pas': {\n get: function(name) {\n if (config.options["chk"+name]) {\n return encodeCookie(config.options[name].toString());\n } else {\n return "";\n }\n },\n set: function(name,value) {config.options[name] = decodeCookie(value);}\n }\n});\n\n// need to reload options to load passwordOptions\nloadOptionsCookie();\n\n/*\nif (!config.options['pasPassword'])\n config.options['pasPassword'] = '';\n\nmerge(config.optionsDesc,{\n pasPassword: "Test password"\n });\n*/\n//}}}\n\n/***\n|''Name:''|UploadPlugin|\n|''Description:''|Save to web a TiddlyWiki|\n|''Version:''|4.1.0|\n|''Date:''|May 5, 2007|\n|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|\n|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#[[BSD open source license]] ]]|\n|''~CoreVersion:''|2.2.0 (#3125)|\n|''Requires:''|PasswordOptionPlugin|\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 4, minor: 1, revision: 0,\n date: new Date("May 5, 2007"),\n source: 'http://tiddlywiki.bidix.info/#UploadPlugin',\n author: 'BidiX (BidiX (at) bidix (dot) info',\n coreVersion: '2.2.0 (#3125)'\n};\n\n//\n// Environment\n//\n\nif (!window.bidix) window.bidix = {}; // bidix namespace\nbidix.debugMode = false; // true to activate both in Plugin and UploadService\n \n//\n// Upload Macro\n//\n\nconfig.macros.upload = {\n// default values\n defaultBackupDir: '', //no backup\n defaultStoreScript: "store.php",\n defaultToFilename: "index.html",\n defaultUploadDir: ".",\n authenticateUser: true // UploadService Authenticate User\n};\n \nconfig.macros.upload.label = {\n promptOption: "Save and Upload this TiddlyWiki with UploadOptions",\n promptParamMacro: "Save and Upload this TiddlyWiki in %0",\n saveLabel: "save to web", \n saveToDisk: "save to disk",\n uploadLabel: "upload" \n};\n\nconfig.macros.upload.messages = {\n noStoreUrl: "No store URL in parmeters or options",\n usernameOrPasswordMissing: "Username or password missing"\n};\n\nconfig.macros.upload.handler = function(place,macroName,params) {\n if (readOnly)\n return;\n var label;\n if (document.location.toString().substr(0,4) == "http") \n label = this.label.saveLabel;\n else\n label = this.label.uploadLabel;\n var prompt;\n if (params[0]) {\n prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], \n (params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);\n } else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);\n};\n\nconfig.macros.upload.action = function(params)\n{\n // for missing macro parameter set value from options\n var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;\n var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;\n var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;\n var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;\n var username = params[4] ? params[4] : config.options.txtUploadUserName;\n var password = config.options.pasUploadPassword; // for security reason no password as macro parameter \n // for still missing parameter set default value\n if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) \n storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;\n if (storeUrl.substr(0,4) != "http")\n storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;\n if (!toFilename)\n toFilename = bidix.basename(window.location.toString());\n if (!toFilename)\n toFilename = config.macros.upload.defaultToFilename;\n if (!uploadDir)\n uploadDir = config.macros.upload.defaultUploadDir;\n if (!backupDir)\n backupDir = config.macros.upload.defaultBackupDir;\n // report error if still missing\n if (!storeUrl) {\n alert(config.macros.upload.messages.noStoreUrl);\n clearMessage();\n return false;\n }\n if (config.macros.upload.authenticateUser && (!username || !password)) {\n alert(config.macros.upload.messages.usernameOrPasswordMissing);\n clearMessage();\n return false;\n }\n bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false; \n};\n\nconfig.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) \n{\n if (!storeUrl)\n return null;\n var dest = bidix.dirname(storeUrl);\n if (uploadDir && uploadDir != '.')\n dest = dest + '/' + uploadDir;\n dest = dest + '/' + toFilename;\n return dest;\n};\n\n//\n// uploadOptions Macro\n//\n\nconfig.macros.uploadOptions = {\n handler: function(place,macroName,params) {\n var wizard = new Wizard();\n wizard.createWizard(place,this.wizardTitle);\n wizard.addStep(this.step1Title,this.step1Html);\n var markList = wizard.getElement("markList");\n var listWrapper = document.createElement("div");\n markList.parentNode.insertBefore(listWrapper,markList);\n wizard.setValue("listWrapper",listWrapper);\n this.refreshOptions(listWrapper,false);\n var uploadCaption;\n if (document.location.toString().substr(0,4) == "http") \n uploadCaption = config.macros.upload.label.saveLabel;\n else\n uploadCaption = config.macros.upload.label.uploadLabel;\n \n wizard.setButtons([\n {caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, \n onClick: config.macros.upload.action},\n {caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}\n \n ]);\n },\n refreshOptions: function(listWrapper) {\n var uploadOpts = [\n "txtUploadUserName",\n "pasUploadPassword",\n "txtUploadStoreUrl",\n "txtUploadDir",\n "txtUploadFilename",\n "txtUploadBackupDir",\n "chkUploadLog",\n "txtUploadLogMaxLine",\n ]\n var opts = [];\n for(i=0; i<uploadOpts.length; i++) {\n var opt = {};\n opts.push()\n opt.option = "";\n n = uploadOpts[i];\n opt.name = n;\n opt.lowlight = !config.optionsDesc[n];\n opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];\n opts.push(opt);\n }\n var listview = ListView.create(listWrapper,opts,this.listViewTemplate);\n for(n=0; n<opts.length; n++) {\n var type = opts[n].name.substr(0,3);\n var h = config.macros.option.types[type];\n if (h && h.create) {\n h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");\n }\n }\n \n },\n onCancel: function(e)\n {\n backstage.switchTab(null);\n return false;\n },\n \n wizardTitle: "Upload with options",\n step1Title: "These options are saved in cookies in your browser",\n step1Html: "<input type='hidden' name='markList'></input><br>",\n cancelButton: "Cancel",\n cancelButtonPrompt: "Cancel prompt",\n listViewTemplate: {\n columns: [\n {name: 'Description', field: 'description', title: "Description", type: 'WikiText'},\n {name: 'Option', field: 'option', title: "Option", type: 'String'},\n {name: 'Name', field: 'name', title: "Name", type: 'String'}\n ],\n rowClasses: [\n {className: 'lowlight', field: 'lowlight'} \n ]}\n}\n\n//\n// upload functions\n//\n\nif (!bidix.upload) bidix.upload = {};\n\nif (!bidix.upload.messages) bidix.upload.messages = {\n //from saving\n invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",\n backupSaved: "Backup saved",\n backupFailed: "Failed to upload backup file",\n rssSaved: "RSS feed uploaded",\n rssFailed: "Failed to upload RSS feed file",\n emptySaved: "Empty template uploaded",\n emptyFailed: "Failed to upload empty template file",\n mainSaved: "Main TiddlyWiki file uploaded",\n mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",\n //specific upload\n loadOriginalHttpPostError: "Can't get original file",\n aboutToSaveOnHttpPost: 'About to upload on %0 ...',\n storePhpNotFound: "The store script '%0' was not found."\n};\n\nbidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)\n{\n var callback = function(status,uploadParams,original,url,xhr) {\n if (!status) {\n displayMessage(bidix.upload.messages.loadOriginalHttpPostError);\n return;\n }\n if (bidix.debugMode) \n alert(original.substr(0,500)+"\sn...");\n // Locate the storeArea div's \n var posDiv = locateStoreArea(original);\n if((posDiv[0] == -1) || (posDiv[1] == -1)) {\n alert(config.messages.invalidFileError.format([localPath]));\n return;\n }\n bidix.upload.uploadRss(uploadParams,original,posDiv);\n };\n \n if(onlyIfDirty && !store.isDirty())\n return;\n clearMessage();\n // save on localdisk ?\n if (document.location.toString().substr(0,4) == "file") {\n var path = document.location.toString();\n var localPath = getLocalPath(path);\n saveChanges();\n }\n // get original\n var uploadParams = Array(storeUrl,toFilename,uploadDir,backupDir,username,password);\n var originalPath = document.location.toString();\n // If url is a directory : add index.html\n if (originalPath.charAt(originalPath.length-1) == "/")\n originalPath = originalPath + "index.html";\n var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);\n var log = new bidix.UploadLog();\n log.startUpload(storeUrl, dest, uploadDir, backupDir);\n displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));\n if (bidix.debugMode) \n alert("about to execute Http - GET on "+originalPath);\n var r = doHttp("GET",originalPath,null,null,null,null,callback,uploadParams,null);\n if (typeof r == "string")\n displayMessage(r);\n return r;\n};\n\nbidix.upload.uploadRss = function(uploadParams,original,posDiv) \n{\n var callback = function(status,params,responseText,url,xhr) {\n if(status) {\n var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\sn", responseText.indexOf("destfile:")));\n displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);\n bidix.upload.uploadMain(params[0],params[1],params[2]);\n } else {\n displayMessage(bidix.upload.messages.rssFailed); \n }\n };\n // do uploadRss\n if(config.options.chkGenerateAnRssFeed) {\n var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";\n var rssUploadParams = Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);\n bidix.upload.httpUpload(rssUploadParams,convertUnicodeToUTF8(generateRss()),callback,Array(uploadParams,original,posDiv));\n } else {\n bidix.upload.uploadMain(uploadParams,original,posDiv);\n }\n};\n\nbidix.upload.uploadMain = function(uploadParams,original,posDiv) \n{\n var callback = function(status,params,responseText,url,xhr) {\n var log = new bidix.UploadLog();\n if(status) {\n // if backupDir specified\n if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {\n var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\sn", responseText.indexOf("backupfile:")));\n displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);\n }\n var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\sn", responseText.indexOf("destfile:")));\n displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);\n store.setDirty(false);\n log.endUpload("ok");\n } else {\n alert(bidix.upload.messages.mainFailed);\n displayMessage(bidix.upload.messages.mainFailed);\n log.endUpload("failed"); \n }\n };\n // do uploadMain\n var revised = bidix.upload.updateOriginal(original,posDiv);\n bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);\n};\n\nbidix.upload.httpUpload = function(uploadParams,data,callback,params)\n{\n var localCallback = function(status,params,responseText,url,xhr) {\n url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));\n if (xhr.status == httpStatus.NotFound)\n alert(bidix.upload.messages.storePhpNotFound.format([url]));\n if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {\n alert(responseText);\n if (responseText.indexOf("Debug mode") >= 0 )\n responseText = responseText.substring(responseText.indexOf("\sn\sn")+2);\n } else if (responseText.charAt(0) != '0') \n alert(responseText);\n if (responseText.charAt(0) != '0')\n status = null;\n callback(status,params,responseText,url,xhr);\n };\n // do httpUpload\n var boundary = "---------------------------"+"AaB03x"; \n var uploadFormName = "UploadPlugin";\n // compose headers data\n var sheader = "";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data; name=\s"";\n sheader += uploadFormName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+uploadParams[3] +\n ";user=" + uploadParams[4] +\n ";password=" + uploadParams[5] +\n ";uploaddir=" + uploadParams[2];\n if (bidix.debugMode)\n sheader += ";debug=1";\n sheader += ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data; name=\s"userfile\s"; filename=\s""+uploadParams[1]+"\s"\sr\sn";\n sheader += "Content-Type: text/html;charset=UTF-8" + "\sr\sn";\n sheader += "Content-Length: " + data.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n data = sheader + data + strailer;\n if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\sn with \sn"+data.substr(0,500)+ " ... ");\n var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);\n if (typeof r == "string")\n displayMessage(r);\n return r;\n};\n\n// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls\nbidix.upload.updateOriginal = function(original, posDiv)\n{\n if (!posDiv)\n posDiv = locateStoreArea(original);\n if((posDiv[0] == -1) || (posDiv[1] == -1)) {\n alert(config.messages.invalidFileError.format([localPath]));\n return;\n }\n var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\sn" +\n store.allTiddlersAsHtml() + "\sn" +\n original.substr(posDiv[1]);\n var newSiteTitle = getPageTitle().htmlEncode();\n revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");\n revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");\n revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");\n revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");\n revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");\n return revised;\n};\n\n//\n// UploadLog\n// \n// config.options.chkUploadLog :\n// false : no logging\n// true : logging\n// config.options.txtUploadLogMaxLine :\n// -1 : no limit\n// 0 : no Log lines but UploadLog is still in place\n// n : the last n lines are only kept\n// NaN : no limit (-1)\n\nbidix.UploadLog = function() {\n if (!config.options.chkUploadLog) \n return; // this.tiddler = null\n this.tiddler = store.getTiddler("UploadLog");\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = "UploadLog";\n this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nbidix.UploadLog.prototype.addText = function(text) {\n if (!this.tiddler)\n return;\n // retrieve maxLine when we need it\n var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);\n if (isNaN(maxLine))\n maxLine = -1;\n // add text\n if (maxLine != 0) \n this.tiddler.text = this.tiddler.text + text;\n // Trunck to maxLine\n if (maxLine >= 0) {\n var textArray = this.tiddler.text.split('\sn');\n if (textArray.length > maxLine + 1)\n textArray.splice(1,textArray.length-1-maxLine);\n this.tiddler.text = textArray.join('\sn'); \n }\n // update tiddler fields\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n store.addTiddler(this.tiddler);\n // refresh and notifiy for immediate update\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n};\n\nbidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n if (!this.tiddler)\n return;\n var now = new Date();\n var text = "\sn| ";\n var filename = bidix.basename(document.location.toString());\n if (!filename) filename = '/';\n text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";\n text += config.options.txtUserName + " | ";\n text += "[["+filename+"|"+location + "]] |";\n text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";\n text += uploadDir + " | ";\n text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";\n text += backupDir + " |";\n this.addText(text);\n};\n\nbidix.UploadLog.prototype.endUpload = function(status) {\n if (!this.tiddler)\n return;\n this.addText(" "+status+" |");\n};\n\n//\n// Utilities\n// \n\nbidix.checkPlugin = function(plugin, major, minor, revision) {\n var ext = version.extensions[plugin];\n if (!\n (ext && \n ((ext.major > major) || \n ((ext.major == major) && (ext.minor > minor)) ||\n ((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {\n // write error in PluginManager\n if (pluginInfo)\n pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);\n eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"\n }\n};\n\nbidix.dirname = function(filePath) {\n if (!filePath) \n return;\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n } else {\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n }\n};\n\nbidix.basename = function(filePath) {\n if (!filePath) \n return;\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("#")) != -1) \n filePath = filePath.substring(0, lastpos);\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(lastpos + 1);\n } else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n};\n\nbidix.initOption = function(name,value) {\n if (!config.options[name])\n config.options[name] = value;\n};\n\n//\n// Initializations\n//\n\n// require PasswordOptionPlugin 1.0.1 or better\nbidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);\n\n// styleSheet\nsetStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");\n\n//optionsDesc\nmerge(config.optionsDesc,{\n txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",\n txtUploadFilename: "Filename of the uploaded file (default: in index.html)",\n txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",\n txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",\n txtUploadUserName: "Upload Username",\n pasUploadPassword: "Upload Password",\n chkUploadLog: "do Logging in UploadLog (default: true)",\n txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"\n});\n\n// Options Initializations\nbidix.initOption('txtUploadStoreUrl','');\nbidix.initOption('txtUploadFilename','');\nbidix.initOption('txtUploadDir','');\nbidix.initOption('txtUploadBackupDir','');\nbidix.initOption('txtUploadUserName','');\nbidix.initOption('pasUploadPassword','');\nbidix.initOption('chkUploadLog',true);\nbidix.initOption('txtUploadLogMaxLine','10');\n\n\n/* don't want this for tiddlyspot sites\n\n// Backstage\nmerge(config.tasks,{\n uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}\n});\nconfig.backstageTasks.push("uploadOptions");\n\n*/\n\n\n//}}}\n\n\n