* Add some help tiddlers tagged with "help"\n* Create a "Help" button that opens the "help" tagtiddler\n* Put link on the side / top bar
Need to be able to bring Tiddlers to the front when you start dragging them:\n\n* ==Remove element then addFirstChild?==\n* ==Increase z-index?==\n* ==Need solid background colour==\n\nOn mousedown now brings the tiddler div to the front, by removing it from its parent then re-attaching it.
!General\n* ==If animation is on layout has problems== disabled now\n* ==Move functionality into macros rather than external JS file ... it's just easier developing that way ;-)==\n* After editing a resized tiddler the internal / scrollable tiddler display area remembers the initial size\n\n!Internet Explorer\n* ==Resizing makes the toolbar grow massively==\n* ==Scrollbars get in the way of everything==\n* Borders not working properly on window bar buttons\n\n!Opera\n* ==Gradient in toolbar not working==\n* Single click on the toolbar of inactive tiddler starts dragging rather than just bringing to front\n\n!Firefox\n* ==Extra bullets appearing in tag list==\n
When you cascade / auto-layout all tiddlers they should all be resized back to their original size to make it all look neat\n\nThey are now closed then reopened, forcing them back to their original layout.
Need to remove tiddler positions from layout when they're closed and update them when they're moved\n\n
There are various methods that should live on the tiddlyDiv itself - pull these out into a decorate tiddly div function
When you jump to a closed tiddler using the # button it should be expanded as well as being brought to the front
Create a Framing div for the tiddler display / edit area:\n\n* ==Contains the buttons / title bar etc==\n* ==Scrolls inside this so you don't lose the drag bit==\n* Parameterise the minimum tiddler size
Jonny LeRoy works for [[ThoughtWorks|http://www.thoughtworks.com/]] in London and created the TiddlyDesktop enhancements to TiddlyWiki\n\nSee http://www.digitaldimsum.co.uk/ for more TiddlyWiki adaptations.\n\nemail jonny [at] leroy [dot] com
Tiddlers should underlap the sidebars rather than overlapping them.\n\nThe sidebar now stays on top and you can't move a tiddler completely out of the viewable area
!Layout Fixes\n\n* ==Make the resizer look nice and appear in the bottom corner - semi done==\n* ==Add an extra div with padding to frame the content==\n* ==Only make the internal bit scrolling==\n* ==Sort out IE - getting better==\n* ==Change the heading colours==\n* Maybe get some icons (embedded in CSS data?) - maybe better as just text ... \n
Need to make the [[_TagChooser]] macro work with v2.0
!For v 1.0 (beta 2) (2 Jan 2006)\n* ''Save layout'' - remembers the size of the tiddlers, whether they're collapsed and how they're stacked.\n* ''Sidebar on top'' - tiddlers now appear under the top and side bars, and you can't drag them completely off the screen.\n* ''Long tiddlers scroll'' - when you open a long tiddler the size of the window containing it is fixed so it shouldn't stretch off the bottom of the screen\n* ''Desktop Buttons'' now sit in the top bar\n\n!For v 1.0 (beta 1) (31 Dec 2005)\n* ''Save layout'' - you can now save the current layout to a hidden tiddler so that when you revisit the wiki you will get the same layout.\n* ''Jump to Tiddler expands it''\n* ''Cascade resets tiddlers' size''\n* All code, templates and styling now in [[_TiddlyDesktopKernel]] macro\n\n!For v 0.1.1 (30 Dec 2005)\n* Fixed various resizing / collapsing issues in IE and Opera\n* Stopped window bar from growing when you resize\n* Made the gradient appear in IE and Opera\n* Tidied up some of the stylings a bit\n* Disabled animations since it was messing with the layout\n* Highlight the window bar when the tiddler is selected\n* Fixed a bug I'd introduced in forEachTiddler\n\nThanks to Elise for some much needed cross-browser / platform QA\n\n!For v 0.1 (30 Dec 2005)\n* All the initial TiddlyDesktop work\n* Added a list of macros to the "more" list tab\n\n!Fixed List\n<<tagList fixed>>
When a long tiddler opens it shouldn't go off the bottom of the screen.\n\n* Limit the length of the tiddler when we open it\n** By fixing the max size to 400px\n** ==By making sure it's not off the bottom of the screen?==
Save the current layout into the a special tiddler [[__tiddlyDesktopLayout]] so that we can come back to the same layout.\n\nTry it here <<saveLayout>> if you want.\n\n!Done\n* ==Create macro button for menu "save layout"==\n* ==Serialize the Layout.tiddlers array to tiddler==\n* ==Have method to restore layout based on array==\n* ==Store the size and whether the tiddler is collapsed in the layout so we can restore that too.==\n* ==Store the z-index so the tiddlers stack in the same way==
Search results don't look too good since most of them are hidden behind the front window, or are below the visible section of the tiddler display area.\n\nMaybe create simple search results box - with lists of tiddlers found and links to them. Could put in the sentence the results are found in.\n\nCheck out Udo's search plugin to see if that can help
<<list shadowed>>
Set the Tiddlers free!
TiddlyDesktop v1.0 (beta 2)
http://www.digitaldimsum.co.uk/tiddly/tiddlydesktop/
Import the smiley macro cos it's fun
!Introducing v1.0 (beta 2) - 2 Jan 2006\nA new layout for TiddlyWiki, made by JonnyLeRoy, allowing you to move tiddlers around and resize them. Still in @@beta@@, but now working quite well in most browsers. Tested most in Firefox 1.5 on Windows. The latest version lives [[here|http://www.digitaldimsum.co.uk/tiddly/tiddlydesktop/]]\n\n!The idea\nAs TiddlyWiki has been progressing it seems to have been getting closer and closer to an operating system rather than just a content management system. Borrowing a few ideas from [[Joe Rai|http://www.cs.utexas.edu/~joeraii/dragn/]], [[YATWA|http://www.rumsby.org/yatwa/]] and some code from [[young pup|http://www.youngpup.net]] I started trying to see if I could make TiddlyWiki more like a desktop ...\n\nOnly part of the way there so far, but it looks promising. Thanks as ever to [[Jeremy Ruston|http://tiddlywiki.com/#JeremyRuston]] and the rest of the [[Tiddly Developers|http://groups.google.com/group/TiddlyWikiDev]]\n\n!What you can do\nYou can:\n* @@''move tiddlers''@@ by dragging the title bar\n* @@''resize tiddlers''@@ by grabbing the "resize me" link that floats vaguely near the bottom right corner of the tiddler\n* @@''collapse / expand tiddlers''@@ by double clicking the toolbar or using the -/+ signs in the toolbar\n* @@''auto cascade tiddlers''@@ to position them nicely when you open lots of them\n* @@''collapse / expand all''@@ from the sidebar\n* @@''bring tiddler to front''@@ by clicking on it\n* @@''save and restore layout''@@ - stored in a hidden tiddler\n* @@''err that's it''@@ for now, but more coming soon\n* @@''oh yes''@@ the message box has moved to the sidebar and now disappears after 4 seconds ... which makes me very happy\n\nSee RecentChanges for more details.\n\n!Technical\nThis version is based on TW 2.0.0 (beta 6). All the code, templates and styles are held in the [[_TiddlyDesktopKernel]] macro. If you want to import it just grab that and dump it into your version. Probably best to get the DIV from the source so no lines are wrapped.\n\n!Todo List\n<<tagList todo>>\n
The original - http://www.tiddlywiki.com\n
Would be a nice compliment to cascading all tiddlers to tile them.\n\n* Expand all (initial size?)\n* Place so not overlapping\n* Don't overlap with menus\n\nThink this will have to be low-priority for now.\n\n!Layout Issues\n* Display them in columns? \n* Wouldn't know when to start new column\n* If we go left to right it would be best if we ordered them by size, trying to get pairs of similar sized tiddlers together ...\n
It would be nice to have Ctrl+Z undo the last edit you made - I keep wanting to do that ...\n\nWe would need to:\n* Store the last tiddler __before__ it was saved (maybe we could store a whole stack of them?)\n* Map Ctrl+Z to a function that saved the previous version of the tiddler
/***\nThanks to [[Roman Porotnikov|http://www.jroller.com/page/deep/20030701]]\n\nNB this systemConfig needs to be evaluated before other ones \nthat use the Aspects so the name starts with "."\nsince they're loaded alphabetically\nshould really put it into the main source code, but\nwanted to keep everything upgrade-proof\n***/\n\n/*{{{*/\n\nAspects = new Object();\n\nAspects.addBefore = function(obj, fname, before) {\n var oldFunc = obj[fname];\n obj[fname] = function() {\n return oldFunc.apply(this, before(arguments, oldFunc, this));\n };\n};\n\nAspects.addAfter = function(obj, fname, after) {\n var oldFunc = obj[fname];\n obj[fname] = function() {\n return after(oldFunc.apply(this, arguments), arguments, oldFunc, this);\n };\n};\n\nAspects.addAround = function(obj, fname, around) {\n var oldFunc = obj[fname];\n obj[fname] = function() {\n return around(arguments, oldFunc, this);\n };\n};\n\n/*}}}*/\n
///////////////////////////////////////////////////////////////\n// Requires http://www.digitaldimsum.co.uk/#_.FunctionDecorator\n///////////////////////////////////////////////////////////////\n\nAspects.addBefore(this, "onClickTagOpenAll", function(args) {\n story.closeAllTiddlers();\n return args;\n});
/***\n|Name|''List Tags By Popularity''|\n|Version|''1.0''|\n|TW Version|''2.0.0 (beta 6)''|\n|Author|''Jonny LeRoy''|\n\n!Overview\nThis macro changes the default ordering for the "Tags" menu list; ordering by the amount of Tiddlers with that tag, rather than a simple alphabetic ordering.\n\n!The Macro\n***/\n\n/*{{{*/\nTiddlyWiki.prototype.getTagsOld = TiddlyWiki.prototype.getTags;\n\nTiddlyWiki.prototype.getTags = function() {\n return this.getTagsOld().sort(function (a,b) {return b[1] - a[1]})\n}\n/*}}}*/\n
///////////////////////////////////////////////////////////////\n// Requires http://www.digitaldimsum.co.uk/#_.FunctionDecorator\n///////////////////////////////////////////////////////////////\n\nfunction setUpTagPromptZone(retVal, args, oldFunc, src) {\n var title = args[0];\n var tagsBox = document.getElementById("editorTags" + title);\n if (tagsBox) tagsBox.setAttribute("autocomplete","off");\n \n loadHotTagSuggestions(title);\n \n var tagsBox = document.getElementById("editorTags" + title);\n if (tagsBox) {\n tagsBox.tiddlerTitle = title;\n tagsBox.onkeydown = onChangeEditorTags;\n }\n \n return retVal;\n}\n\n\nfunction loadHotTagSuggestions(title,filter) {\n var theWrapper = document.getElementById("editorWrapper" + title);\n var theOldZone = document.getElementById("tagPromptZone"+title);\n if (theOldZone)\n theOldZone.parentNode.removeChild(theOldZone);\n var theZone = createTiddlyElement(theWrapper,"div","tagPromptZone"+title,"tagPromptZone");\n\n var tags = store.getTags();\n var lingo = config.views.editor.tagChooser;\n \n var doneHighlight = false;\n for (t=0; t<tags.length; t++) {\n if (filter && filter.length > 0 && tags[t][0].indexOf(filter) != 0) continue;\n var theTag = createTiddlyButton(theZone,tags[t][0],lingo.tagTooltip.format([tags[t][0]]),onClickAddTagPopup,null,"button");\n theTag.setAttribute("tag",tags[t][0]);\n theTag.setAttribute("tiddler",title);\n \n if (!doneHighlight) {\n theTag.id = "hotSuggestion";\n doneHighlight = true;\n }\n theZone.appendChild(document.createTextNode(" "));\n }\n}\n\nfunction onChangeEditorTags(e) {\n if (!e) e = window.event;\n var tagsBox = resolveTarget(e);\n if(tagsBox) {\n var pos = tagsBox.value.lastIndexOf(" ");\n if (e.keyCode == 9) {\n tagsBox.value = tagsBox.value.substring(0,pos);\n useSelectedTagSuggestion();\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n } else {\n window.setTimeout(function updateTagSuggestions() {\n var tagSuggestionFilter = tagsBox.value.substr(++pos,tagsBox.value.length);\n loadHotTagSuggestions(tagsBox.tiddlerTitle, \n tagSuggestionFilter.length > 0 ? tagSuggestionFilter : null);\n }, 100);\n }\n }\n return true;\n}\n\nfunction useSelectedTagSuggestion() {\n var selectedTag = document.getElementById("hotSuggestion");\n if (!selectedTag) return;\n var tiddler = selectedTag.getAttribute("tiddler");\n var tag = selectedTag.getAttribute("tag");\n var tagsBox = document.getElementById("editorTags" + tiddler);\n if(tagsBox)\n tagsBox.value += " " + String.encodeTiddlyLink(tag);\n}\n\nAspects.addAfter(this,"createTiddlerEditor",setUpTagPromptZone);\n
//Thanks to Clint Checketts\n\nversion.extensions.tagCloud = {major: 0, minor: 1, revision: 0, date: new Date(2005,7,31)};\n\nconfig.macros.tagCloud = {\n noTags: "No tag cloud created because there are no tags."\n};\n\nconfig.macros.tagCloud.handler = function(place,macroName,params) {\n var tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);\n var tags = store.getTags();\n if(tags.length == 0) createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);\n //Findout the maximum number of tags\n var mostTags = 0;\n for (t=0; t<tags.length; t++) {\n if (tags[t][1] > mostTags) mostTags = tags[t][1];\n }\n //divide the mostTags into 6 segments for the 6 different tagCloud sizes\n var tagSegment = mostTags / 4;\n for (t=0; t<tags.length; t++) {\n var tagCloudElement =createTiddlyElement(tagCloudWrapper,"span",null,null,null);\n tagCloudWrapper.appendChild(document.createTextNode(" "));\n var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip + tags[t][0],onClickTag,"tagCloudtag tagCloud"+(Math.round(tags[t][1]/tagSegment)+1));\n theTag.setAttribute("tag",tags[t][0]);\n }\n};\n\nsetStylesheet(".tagCloud span{height: 1.8em;margin: 3px !important;}.tagCloud1{font-size: 1.2em;}.tagCloud2{font-size: 1.4em;}.tagCloud3{font-size: 1.6em;}.tagCloud4{font-size: 1.8em;}.tagCloud5{font-size: 1.8em;font-weight: bold;}","tagCloudsStyles");\n
/***\n!Tiddly Desktop Core Logic\n|''name''|_TiddlyDestopKernel|\n|''version''|1.0 (beta 2)|\n|''date''|2 Jan 2006|\n|''author''|JonnyLeRoy|\n|''TW version''|2.0.0 (beta 6)|\n\nThis macro contains all the logic and styles to turn a standard TiddlyWiki into a TiddlyDesktop\n\n!Tiddly Desktop\nCore stuff - should move more functionality (like decorating Tiddlers) into here\n\n***/\n\n/*{{{*/\nvar TiddlyDesktop = {\n canvas: {\n top: 39,\n left: 60\n },\n \n cascade: {\n top: 20,\n left: 20\n }\n};\n\n/*}}}*/\n\n/***\n!List Macros Tab\n***/\n\n/*{{{*/\n\nconfig.shadowTiddlers.TabMore = "<<tabs txtMoreTab Macros 'Macros / Plugins' TabMoreMacros Missing 'Missing tiddlers' TabMoreMissing Orphans 'Orphaned tiddlers' TabMoreOrphans>>";\nconfig.shadowTiddlers.TabMoreMacros = "<<list macros>>";\n\nconfig.macros.list.macros = {\n prompt: "All macros / plugins",\n \n handler: function(params) {\n return store.getTaggedTiddlers("systemConfig", "title");\n }\n}\n\n/*}}}*/\n\n/***\n!Jump Macro\n***/\n\n/*{{{*/\n\nconfig.macros.jump = {\n label: "jump",\n prompt: "Jump to any open Tiddler",\n\n handler: function(place) {\n createTiddlyButton(place,this.label,this.prompt,function(event) {\n config.commands.jump.handler(event,this);\n });\n }\n}\n\n\n\n/*}}}*/\n\n/***\n!Collapse Tiddler\n***/\n\n/*{{{*/\n\nconfig.views.wikified.collapseTiddler = {\n text: "-",\n tooltip: "Collapse this tiddler",\n toggleText: "+",\n toggleTooltip: "Expand this tiddler"\n};\n\nconfig.commands.collapseTiddler = {\n text: config.views.wikified.collapseTiddler.text,\n tooltip: config.views.wikified.collapseTiddler.tooltip,\n toggleText: config.views.wikified.collapseTiddler.toggleText,\n toggleTooltip: config.views.wikified.collapseTiddler.toggleTooltip,\n\n handler: function(event,src,title) {\n this.toggle(title, true, true);\n },\n \n toggle: function(title, collapse, expand) {\n var theDiv = document.getElementById(story.idPrefix + title);\n var theLink = this.getCollapseLink(theDiv);\n\n var div = this.findCollapseDiv(theDiv);\n if (expand && div.style.display == 'none') {\n this.toggleDisplay(theDiv, div, theLink, 'block', theDiv.style._oldHeight, this.text, this.tooltip)\n } else if (collapse) {\n if (theDiv.style.height) {\n theDiv.style._oldHeight = theDiv.style.height;\n }\n\n this.toggleDisplay(theDiv, div, theLink, 'none', div.style.height, this.toggleText, this.toggleTooltip)\n }\n },\n \n getCollapseLink: function(theDiv) {\n var links = theDiv.getElementsByTagName('a');\n for (i in links) {\n var link = links[i];\n if (link.innerHTML == this.text || link.innerHTML == this.toggleText) {\n return link;\n }\n }\n },\n \n findCollapseDiv: function(theDiv) {\n var children = theDiv.childNodes;\n \n for (i in children) {\n var div = children[i];\n if (div && div.className == 'collapsible') {\n return div;\n }\n }\n },\n \n toggleDisplay: function(theDiv, div, theLink, display, height, text, tooltip) {\n div.style.display = display;\n theLink.innerHTML = text;\n theLink.setAttribute('title', tooltip);\n if (typeof height != 'undefined') {\n theDiv.style.height = height;\n }\n theDiv.collapsed = display == 'none';\n }\n \n};\n\n/*}}}*/\n\n/***\n!Collapse / Expand all tiddlers\n***/\n\n/*{{{*/\n\nconfig.macros.collapseAll = {label: "collapse all", prompt: "Collapse all visible Tiddlers"};\nconfig.macros.collapseAll.handler = function(place) {\n createTiddlyButton(place,this.label,this.prompt,function () {story.collapseAll(); return false;});\n}\n\nStory.prototype.collapseAll = function() {\n this.forEachTiddler(function(tiddler,e) {\n config.commands.collapseTiddler.toggle(tiddler,true,false);\n });\n}\n\nconfig.macros.expandAll = {label: "expand all", prompt: "expand all visible Tiddlers"};\nconfig.macros.expandAll.handler = function(place) {\n createTiddlyButton(place,this.label,this.prompt,function () {story.expandAll(); return false;});\n}\n\nStory.prototype.expandAll = function() {\n this.forEachTiddler(function(tiddler,e) {\n config.commands.collapseTiddler.toggle(tiddler,false,true);\n });\n}\n\nconfig.macros.autoLayout = {label: "cascade", prompt: "Layout all open Tiddlers nicely"};\nconfig.macros.autoLayout.handler = function(place) {\n createTiddlyButton(place,this.label,this.prompt,function () {layout.autoLayout(); return false;});\n}\n\n/*}}}*/\n/***\n!Tiddler Layout\n***/\n/*{{{*/\n\nfunction Layout() {};\n\nLayout.prototype = {\n tiddlers: [],\n \n add: function(tiddler, nicely) {\n var newPos = {\n id: tiddler.id, \n x: findPosX(tiddler), \n y: findPosY(tiddler),\n z: this.tiddlers.length,\n \n toString: function() {\n var theTiddler = document.getElementById(this.id);\n \n return "\sn{id: '%0', x: %1, y: %2, z: %3, width: %4, height: %5, collapsed: %6}".format([\n this.id, \n this.x, \n this.y, \n this.z, \n theTiddler.clientWidth, \n theTiddler.clientHeight, \n (!!theTiddler.collapsed)\n ]);\n }\n };\n \n this.remove(tiddler);\n \n if (nicely) {\n this.position(newPos, tiddler, true);\n }\n\n this.tiddlers.push(newPos);\n this.tiddlers.sort(function(a, b) {return a.x - b.x});\n },\n \n position: function(newPos, tiddler, nicely) {\n if (nicely) {\n this.cascade(newPos);\n }\n\n tiddler.style.position = 'absolute';\n tiddler.style.left = newPos.x +'px';\n tiddler.style.top = newPos.y +'px';\n \n tiddler.bringToFront()\n },\n \n cascade: function(newPos) {\n for (t in this.tiddlers) {\n var pos = this.tiddlers[t];\n if (Math.abs(pos.x - newPos.x) < TiddlyDesktop.cascade.left) {\n newPos.x += TiddlyDesktop.cascade.left;\n if (Math.abs(pos.y - newPos.y) < TiddlyDesktop.cascade.top) {\n newPos.y += TiddlyDesktop.cascade.top;\n }\n }\n }\n },\n \n remove: function(tiddler) {\n for (t in this.tiddlers) {\n var pos = this.tiddlers[t];\n if (pos.id == tiddler.id) {\n this.tiddlers.splice(t, 1);\n break;\n }\n }\n },\n \n autoLayout: function() {\n var titles = [];\n for (t in this.tiddlers) {\n if (this.tiddlers[t].id) {\n titles.push(this.tiddlers[t].id.substring(story.idPrefix.length));\n }\n }\n story.closeAllTiddlers();\n story.displayTiddlers(null, titles.reverse());\n }, \n \n bringToFront: function(tiddler) {\n var stacked = this.tiddlers.sort(function(a,b) {return a.z - b.z});\n var tz = stacked.length;\n for (t in stacked) {\n var pos = stacked[t];\n if (pos.id == tiddler.id) {\n tz = pos.z;\n pos.z = stacked.length;\n } else if (pos.z > tz) {\n pos.z--;\n }\n }\n },\n \n marshall: function() {\n return "[%0\sn]".format([this.tiddlers.toString()]);\n },\n \n unmarshall: function(serializedLayout) {\n var savedTiddlers = eval(serializedLayout).sort(function(a,b) {return a.z - b.z});\n for (t in savedTiddlers) {\n if (savedTiddlers[t].id) {\n var pos = savedTiddlers[t];\n var title = pos.id.substring(story.idPrefix.length);\n story.displayTiddler(null, title);\n var tiddler = document.getElementById(pos.id);\n this.position(pos, tiddler, false);\n \n if (pos.width) {\n tiddler.style.width = pos.width +'px';\n tiddler.style.height = pos.height +'px';\n if (pos.collapsed) {\n config.commands.collapseTiddler.toggle(title, true, false);\n } else {\n tiddler.scrollable.style.width = (pos.width - 15) +'px';\n tiddler.scrollable.style.height = (pos.height - 60) +'px';\n }\n }\n }\n }\n },\n \n limitHeight: function(tiddlyDiv) {\n tiddlyDiv.findMovingParts = function() {\n var divs = this.getElementsByTagName("div");\n for (d in divs) {\n var div = divs[d];\n if (div && div.className == 'scrollable') {\n this.scrollable = div;\n }else if (div && div.className == 'windowBar') {\n this.windowBar = div;\n }\n }\n };\n \n tiddlyDiv.limitHeight = function() {\n this.findMovingParts();\n \n if (this.clientHeight > 400) {\n this.scrollable.style.height = '380px';\n }\n\n //for IE ... \n if(this.scrollable && this.scrollable.clientWidth >= this.windowBar.clientWidth) {\n this.scrollable.style.width = (this.windowBar.clientWidth - 15) +'px';\n }\n };\n \n tiddlyDiv.limitHeight();\n }\n}\n\nvar layout = new Layout();\n\nStory.prototype.old_closeTiddler = Story.prototype.closeTiddler;\n\nStory.prototype.closeTiddler = function(title,animate,slowly) {\n var tiddler = document.getElementById(this.idPrefix + title);\n if(tiddler != null) {\n layout.remove(tiddler);\n }\n this.old_closeTiddler(title,animate,slowly);\n}\n\n/*}}}*/\n/***\n!Drag Tiddler\n***/\n/*{{{*/\n\nvar lastClicked;\n\nfunction bringToFront() {\n if (lastClicked == this) return;\n lastClicked = this;\n var parent = this.parentNode;\n parent.removeChild(this);\n parent.appendChild(this);\n layout.bringToFront(this);\n}\n\nStory.prototype.old_displayTiddler = Story.prototype.displayTiddler;\n\nStory.prototype.displayTiddler = function(srcElement,title,template,animate,slowly) {\n this.old_displayTiddler(srcElement,title,template,animate,slowly);\n var tiddlyDiv = document.getElementById(this.idPrefix +title);\n var theHandle = tiddlyDiv.getElementsByTagName("div")[0];\n\n layout.limitHeight(tiddlyDiv);\n \n tiddlyDiv.bringToFront = bringToFront;\n tiddlyDiv.onmousedown = bringToFront;\n tiddlyDiv.bringToFront();\n config.commands.collapseTiddler.toggle(title, false, true);\n\n layout.add(tiddlyDiv, true);\n \n if (theHandle) {\n theHandle.fixHeight = function() {\n this.style.height = '1.25em';\n };\n \n theHandle.fixHeight();\n \n theHandle.ondblclick = function(e) {\n this.fixHeight();\n e = fixE(e);\n config.commands.collapseTiddler.handler(e, null, title);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n };\n \n Drag.init(theHandle, tiddlyDiv);\n tiddlyDiv.onDragStart = function(x, y) {\n this.style.borderColor_old = this.style.borderColor;\n this.style.borderColor = 'red';\n }\n tiddlyDiv.onDragEnd = function(x, y) {\n this.style.borderColor = this.style.borderColor_old ? this.style.borderColor_old : '#999';\n layout.add(this, false);\n var sideBar = document.getElementById("sidebar");\n var parent = sideBar.parentNode;\n var top = sideBar.offsetTop;\n parent.removeChild(sideBar);\n parent.appendChild(sideBar);\n sideBar.style.top = top +'px';\n }\n }\n}\n\nStory.prototype.old_refreshTiddler = Story.prototype.refreshTiddler;\nStory.prototype.refreshTiddler = function(title,template,force) {\n var theTiddler = this.old_refreshTiddler(title,template,force);\n layout.limitHeight(theTiddler);\n return theTiddler;\n}\n\n/*}}}*/\n\n/***\n!Resize Tiddler\n***/\n\n/*{{{*/\n\n\nconfig.macros.sizer = {};\n\nconfig.macros.sizer.handler = function(place, macroName, params, wikifier, paramString, tiddler) {\n var theSizer = createTiddlyElement(place,"span",null,"resizer","resize me");\n var theTiddler = document.getElementById(story.idPrefix + tiddler.title);\n Sizer.init(theSizer, theTiddler);\n \n theTiddler.onSizeStartPre = function() {\n this.findMovingParts();\n\n this.scrollable.startHeight = parseInt(this.scrollable.offsetHeight);\n this.scrollable.startWidth = parseInt(this.scrollable.offsetWidth);\n\n this.windowBar.startHeight = parseInt(this.windowBar.clientHeight);\n };\n\n theTiddler.onSizeStartPost = function() {\n this.windowBar.fixHeight();\n };\n\n theTiddler.onSize = function(x, y) {\n\n var nx = x + this.scrollable.startWidth;\n var ny = y + this.scrollable.startHeight;\n\n if (nx < 80) nx = 80;\n if (ny < 50) ny = 50;\n\n this.scrollable.style.width = nx + "px";\n this.scrollable.style.height = ny + "px";\n\n this.windowBar.fixHeight();\n };\n \n};\n\n/*}}}*/\n\n/***\n!Bug Fixes / Core Changes\n***/\n\n/*{{{*/\n\n//Alert errors in systemConfigs if messageArea not yet rendered\nfunction checkDisplay(obj) {\n var oldFunc = obj['displayMessage'];\n obj['displayMessage'] = function(text, linkText) {\n var msgArea = document.getElementById("messageArea");\n if (!msgArea) {\n alert(text);\n return;\n }\n oldFunc.apply(this, arguments);\n \n //remove the message after 4 secs\n setTimeout(clearMessage,4000);\n }\n \n};\n\ncheckDisplay(this);\n\n/*}}}*/\n\n/***\n\n!Core Drag Functionality\nBorrowed from [[DOM Drag|http://www.youngpup.net]] with some changes\n\n***/\n\n/*{{{*/\n\nvar Drag = {\n\n obj : null,\n\n init : function(o, oRoot) {\n o.onmousedown = Drag.start;\n o.root = oRoot && oRoot != null ? oRoot : o ;\n\n if (isNaN(parseInt(o.root.style.left ))) o.root.style.left = "0px";\n if (isNaN(parseInt(o.root.style.top ))) o.root.style.top = "0px";\n\n o.root.onDragStart = new Function();\n o.root.onDragEnd = new Function();\n o.root.onDrag = new Function();\n },\n\n start : function(e) {\n var o = Drag.obj = this;\n e = Drag.fixE(e);\n var y = parseInt(o.root.style.top);\n var x = parseInt(o.root.style.left);\n o.root.onDragStart(x, y);\n\n o.lastMouseX = e.clientX;\n o.lastMouseY = e.clientY;\n\n document.onmousemove = Drag.drag;\n document.onmouseup = Drag.end;\n\n return false;\n },\n\n drag : function(e) {\n e = Drag.fixE(e);\n var o = Drag.obj;\n\n var ey = e.clientY;\n var ex = e.clientX;\n var y = parseInt(o.root.style.top);\n var x = parseInt(o.root.style.left);\n var nx, ny;\n\n nx = x + ((ex - o.lastMouseX) * 1);\n ny = y + ((ey - o.lastMouseY) * 1);\n\n if (ny < TiddlyDesktop.canvas.top) ny = TiddlyDesktop.canvas.top;\n if (nx + o.clientWidth < TiddlyDesktop.canvas.left) nx = TiddlyDesktop.canvas.left - o.clientWidth;\n\n Drag.obj.root.style.left = nx + "px";\n Drag.obj.root.style.top = ny + "px";\n Drag.obj.root.clientX = nx + "px";\n Drag.obj.root.clientY = ny + "px";\n Drag.obj.lastMouseX = ex;\n Drag.obj.lastMouseY = ey;\n\n Drag.obj.root.onDrag(nx, ny);\n return false;\n },\n\n end : function() {\n document.onmousemove = null;\n document.onmouseup = null;\n Drag.obj.root.onDragEnd( parseInt(Drag.obj.root.style.left),\n parseInt(Drag.obj.root.style.top));\n Drag.obj = null;\n },\n\n fixE : function(e) {\n if (typeof e == 'undefined') e = window.event;\n if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;\n if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;\n return e;\n }\n};\n\n/*}}}*/\n\n/***\n\n!Core Sizer Functionality\nStructure taken from [[DOM Drag|http://www.youngpup.net]]\n\n***/\n\n/*{{{*/\n\n\nvar Sizer = {\n\n obj : null,\n startX: 0,\n startY: 0,\n startWidth: 0,\n startHeight: 0,\n\n init : function(o, oRoot) {\n o.onmousedown = Sizer.start;\n o.root = oRoot && oRoot != null ? oRoot : o ;\n\n o.root.onSizeStart = new Function();\n o.root.onSize = new Function();\n },\n\n start : function(e) {\n var o = Sizer.obj = this;\n e = fixE(e);\n\n o.root.onSizeStartPre(e);\n\n Sizer.startHeight = parseInt(o.root.offsetHeight);\n Sizer.startWidth = parseInt(o.root.offsetWidth);\n\n o.root.style.height = Sizer.startHeight +'px';\n o.root.style.width = Sizer.startWidth +'px';\n\n Sizer.startX = e.clientX;\n Sizer.startY = e.clientY;\n \n o.root.onSizeStartPost(e);\n \n document._oldonmousemove = document.onmousemove;\n document._oldonmouseup = document.onmouseup;\n document.onmousemove = Sizer.drag;\n document.onmouseup = Sizer.end;\n\n return false;\n },\n\n drag : function(e) {\n e = fixE(e);\n\n var x = (e.clientX - Sizer.startX);\n var y = (e.clientY - Sizer.startY);\n var nx = x + Sizer.startWidth;\n var ny = y + Sizer.startHeight;\n\n if (nx < 100) nx = 100;\n if (ny < 100) ny = 100;\n\n Sizer.obj.root.style.width = nx + "px";\n Sizer.obj.root.style.height = ny + "px";\n\n Sizer.obj.root.onSize(x, y);\n\n return false;\n },\n\n end : function() {\n document.onmousemove = document._oldonmousemove;\n document.onmouseup = document._oldonmouseup;\n Sizer.obj = null;\n }\n\n};\n\n\nfunction fixE(e) {\n if (typeof e == 'undefined') e = window.event;\n return e;\n}\n\n\n\n/*}}}*/\n/***\n\n!Tag List macro\nSo that you don't need to have a tiddler for the tag\n\n***/\n/*{{{*/\n\n\nconfig.macros.tagList = {listTitle: "List of tiddlers tagged with '%0'", emptyListTitle: "Nothing tagged with '%0'"};\n\nconfig.macros.tagList.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n var title = params[0];\n var tagged = store.getTaggedTiddlers(title);\n var theList = createTiddlyElement(place,"ul");\n\n if (tagged.length == 0) {\n createTiddlyElement(theList,"li",null,null,this.emptyListTitle.format([title]));\n }\n\n for(t in tagged) {\n if (tagged[t].title) {\n createTiddlyLink(createTiddlyElement(theList,"li"),tagged[t].title,true);\n }\n }\n}\n\n\n/*}}}*/\n/***\n\n!Save Layout\nSave the layout to a tiddler for redisplaying later\n\n***/\n/*{{{*/\n\nconfig.macros.saveLayout = {\n label: "save layout", \n prompt: "Save the current layout as the default",\n \n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n createTiddlyButton(place,this.label,this.prompt,this.saveLayout);\n },\n \n saveLayout: function() {\n var tiddlerName = "__tiddlyDesktopLayout";\n var serializedLayout = layout.marshall();\n serializedLayout = "/***\sn@@''This tiddler is auto-generated - don't edit it!''@@\sn***/\sn/*{{{*/\sn"+ serializedLayout +"\sn/*}}}*/\sn";\n var tiddler = store.saveTiddler(tiddlerName,tiddlerName,serializedLayout,config.options.txtUserName,new Date(),"excludeLists");\n\n if (config.options.chkAutoSave) {\n saveChanges();\n }\n }\n};\n\nconfig.macros.restoreLayout = {\n label: "restore layout", \n prompt: "Restores the last saved layout",\n \n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n createTiddlyButton(place,this.label,this.prompt,restart);\n }\n};\n\nthis['restart'] = function() {\n var serializedLayout = store.getTiddlerText("__tiddlyDesktopLayout");\n var start = store.getTiddlerText("DefaultTiddlers");\n if(window.location.hash) {\n story.displayTiddlers(null,convertUTF8ToUnicode(decodeURI(window.location.hash.substr(1))).readBracketedList());\n } else if(serializedLayout) {\n layout.unmarshall(serializedLayout);\n } else if(start) {\n story.displayTiddlers(null,start.readBracketedList());\n }\n}\n\n\n/*}}}*/\n\n/***\n!Config Changes\nSet some text icons for the edit buttons\n***/\n\n/*{{{*/\nconfig.commands.closeTiddler.text = "x";\nconfig.commands.jump.text = "#";\n\n/*}}}*/\n\n/***\nAnimations get in the way of proper display - disable them for now\n***/\n/*{{{*/\nconfig.options.chkAnimate = false;\nconfig.shadowTiddlers.OptionsPanel = config.shadowTiddlers.OptionsPanel.replace(/\sn<<option chkAnimate>> EnableAnimations/, '');\n\n/*}}}*/\n\n/***\n!Shadow Tiddlers\nShadow the StyleSheet and various templates so they're retrievable and can all be imported with a single macro\n\n***/\n\n/*{{{*/\n\nconfig.shadowTiddlers.StyleSheet = "/*{{{*/\sn\snBODY {\sn background-color: #ddd;\sn}\sn\sn.collapsible {\sn margin: 4px;\sn}\sn\sn.scrollable {\sn margin: 4px;\sn overflow: auto;\sn}\sn\sn.windowBar {\sn color: #fff;\sn background-color: #04b;\sn cursor:pointer;\sn padding: 2px 2px 2px 4px;\sn}\sn\sn.windowBar .title {\sn color: #ccc;\sn font-size: 1em;\sn cursor:move;\sn}\sn\sn.selected .windowBar .title {\sn color: #fff;\sn}\sn\sn.tiddler { \sn position: relative; \sn width: 500px; \sn border: solid 1px;\sn border-color: #999;\sn background-color: #fff;\sn padding: 0px;\sn}\sn\sn.viewer {\sn background:white;\sn}\sn\sn\sn.windowToolbar {\sn text-align: right;\sn float: right;\sn}\sn\sn.collapsible .toolbar {\sn text-align: right;\sn margin-top: 4px;\sn}\sn\sn.sizer {\sn text-align: right;\sn cursor: move;\sn background-color: #ccc;\sn}\sn\sn.sizer .resizer {\sn color: #fff;\sn background-color: #aaa;\sn padding: 0px 2px 0px 2px;\sn}\sn\sn.tiddler .windowBar .button {\sn color: #04b;\sn background-color: #fff;\sn margin-right: 2px;\sn padding: 0em 0.4em;\sn border: solid 1px #ccc;\sn}\sn\sn.tiddler .windowBar .button:Hover {\sn background-color: #8cf;\sn border-color: #04b;\sn}\sn\snh1,h2,h3,h4,h5 {\sn color: #04b;\sn background: transparent;\sn padding-left: 2px;\sn}\sn\snh1,h2 {\sn color: #04b;\sn background: transparent;\sn border-bottom: solid 1px #04b;\sn}\sn\sn.tagging A, .tagged A {\sn border: none !important;\sn background-color: transparent !important;\sn}\sn\sn.selected .tagging A, .selected .tagged A {\sn}\sn\sn.tagging A:Hover, .tagged A:Hover {\sn border: none !important;\sn background-color: transparent !important;\sn color: #f00 !important;\sn}\sn\sn#sidebarCopyright {\sn background-color: #ddd;\sn color: #666;\sn padding: 10px 4px 20px 4px;\sn}\sn\sn#sidebarCopyright A {\sn color: #555;\sn}\sn\sn#sidebarCopyright A:Hover {\sn color: #f00;\sn background-color: transparent;\sn}\sn\sn\sn#titleLine {\sn padding: 1em 0em 1em 0em;\sn}\sn\sn#siteTitle {\sn font-size: 1em;\sn} \sn\sn#siteSubtitle {\sn font-size: .9em;\sn}\sn\sn#displayArea {\sn margin: 1em 17em 0em 2em;\sn}\sn\sn.subtitle {\sn font-size: 1em;\sn text-align: right;\sn float: right;\sn padding-top: 1em;\sn}\sn\sn#desktopButtons {\sn float: right;\sn}\sn\sn#desktopButtons A {\sn font-weight: normal !important;\sn margin-right: .25em;\sn color: #ccc;\sn font-size: .9em;\sn padding: .1em .5em;\sn border: solid 1px #18f;\sn}\sn\sn#desktopButtons A:Hover {\sn color: #fff;\sn border: solid 1px #04b;\sn}\sn\sn/*}}}*/\sn\sn";\nconfig.shadowTiddlers.EditTemplate = "<div macro='gradient horiz #0044bb #1188ff #ffffff' class='windowBar'>\sn<span class='windowToolbar' macro='toolbar jump collapseTiddler closeTiddler'></span>\sn<span class='title' macro='view title'></span></div>\sn\sn<div class='collapsible'>\sn<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>\sn<div class='editor' macro='edit title'></div>\sn<div class='editor' macro='edit text'></div>\sn<div class='editor' macro='edit tags'></div>\sn<div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>\sn<div macro='sizer' class='sizer'></div>\sn</div>";\nconfig.shadowTiddlers.PageTemplate = "<div id='header'>\sn<div id='titleLine' macro='gradient vert #1188ff #0044bb'>\sn<span id='desktopButtons' refresh='content' tiddler='DesktopButtons'></span>\sn<span id='siteTitle' refresh='content' tiddler='SiteTitle'></span>\sn<span id='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\sn</div>\sn</div>\sn<div id='sidebar'>\sn<div id='messageArea'></div>\sn<div macro='gradient vert #0044bb #001144'><div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div></div>\sn<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\sn<div id='sidebarCopyright' refresh='content' tiddler='Copyright'></div>\sn</div>\sn<div id='displayArea'>\sn<div id='tiddlerDisplay'></div>\sn</div>";\nconfig.shadowTiddlers.ViewTemplate = "<div macro='gradient horiz #0044bb #1188ff #ffffff' class='windowBar'>\sn<span class='windowToolbar' macro='toolbar jump collapseTiddler -closeTiddler'></span>\sn<span class='title' macro='view title'></span></div>\sn<div class='collapsible'>\sn<div class='toolbar' macro='toolbar +editTiddler permalink references closeOthers'></div>\sn<div class='scrollable'>\sn<div class='tagging' macro='tagging'></div>\sn\sn<div class='tagged' macro='tags'></div>\sn<div class='viewer' macro='view text wikified'></div>\sn<div class='subtitle'>\sn<span macro='view modified date [[DD/MM/YYYY]]'></span>\sn (created: <span macro='view created date [[DD/MM/YYYY]]'></span>)\sn</div>\sn<div class='tagClear'></div>\sn</div>\sn<div macro='sizer' class='sizer'></div>\sn</div>";\nconfig.shadowTiddlers.SideBarOptions = "<<search>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel 'options \su00BB' 'Change TiddlyWiki advanced options'>>",\nconfig.shadowTiddlers.Copyright = "\snTiddlyWiki was created by [[Jeremy Ruston|http://tiddlywiki.com/#JeremyRuston]] and is published under an [[Open Source License|http://tiddlywiki.com/#OpenSourceLicense]]\sn\snTiddlyDesktop was created by JonnyLeRoy and is released under the same terms.\sn\snFeel free to sue me if it breaks your air-traffic-control system. It worked on my machine.";\nconfig.shadowTiddlers.DesktopButtons = "<<closeAll>><<jump>><<collapseAll>><<autoLayout>><<expandAll>><<saveLayout>><<restoreLayout>>";\n\n/*}}}*/\n\n
/***\n|Name|''Use Backup Directory''|\n|Version|''1.1''|\n|TW Version|''2.0.0 (beta 6)''|\n|Author|''JonnyLeRoy''|\n\n@@''This Function Requires [[FunctionDecorator|http://www.digitaldimsum.co.uk/#_.FunctionDecorator]]''@@\n\n!Overview\nThis macro puts the backup files into a named subdirectory. The directory is called "backup" by default, but can be changed via the AdvancedOptions.\n\n!The Macro\n\n''The advanced options''\n***/\n\n/*{{{*/\nconfig.options.txtBackupDir = "backup";\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option txtBackupDir>> Backup Subdirectory ";\n/*}}}*/\n\n/***\n''The main macro function''\n***/\n\n/*{{{*/\nfunction alterBackupDir(args) {\n var path = args[0];\n var re = new RegExp("\s.[0-9]+\s.html");\n if (re.test(path)) {\n var backSlash = true;\n var dirPathPos = path.lastIndexOf("\s\s");\n if (dirPathPos == -1) {\n dirPathPos = path.lastIndexOf("/");\n backSlash = false;\n }\n var backupPath = path.substr(0,dirPathPos) + (backSlash ? "\s\s" : "/");\n backupPath += config.options.txtBackupDir + path.substr(dirPathPos, path.length - dirPathPos);\n \n args[0] = backupPath;\n }\n return args;\n}\n\n/*}}}*/\n\n/***\n''Apply the new function before the existing saveFile function''\n\n***/\n\n/*{{{*/\n\nAspects.addBefore(this,"saveFile",alterBackupDir);\n/*}}}*/\n
/***\n@@''This tiddler is auto-generated - don't edit it!''@@\n***/\n/*{{{*/\n[\n{id: 'tiddlerUndoLastChange', x: 24, y: 51, z: 0, width: 500, height: 239, collapsed: false},\n{id: 'tiddlerTileTiddlers', x: 44, y: 71, z: 1, width: 500, height: 375, collapsed: false},\n{id: 'tiddlerMakeTheTagChooserWorkWith2.0', x: 64, y: 91, z: 2, width: 500, height: 116, collapsed: false},\n{id: 'tiddlerBugs', x: 84, y: 111, z: 3, width: 500, height: 444, collapsed: false},\n{id: 'tiddlerAddHelpSections', x: 104, y: 131, z: 4, width: 500, height: 171, collapsed: false},\n{id: 'tiddlerRecentChanges', x: 124, y: 151, z: 5, width: 500, height: 444, collapsed: false},\n{id: 'tiddlerTiddlyDesktop', x: 144, y: 171, z: 7, width: 500, height: 444, collapsed: false}\n]\n/*}}}*/\n