<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n^^(override with Control or other modifier key)^^\n<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP<cond config.options.chkHttpReadOnly==false>\n<<option chkConfirmDelete>> ConfirmBeforeDeleting\nMaximum number of lines in a tiddler edit box: <<option txtMaxEditRows>>\n<<option chkInsertTabs>> Use tab key to insert tab characters instead of jumping to next field\n</cond>\n<<option pasUploadPassword>>
//{{{\nconfig.macros.binaryData = { };\n\nconfig.macros.binaryData.convertHexToBinary = function( paramSourceString, paramOffset, paramBytes ) {\n var digits = paramBytes * 2;\n var result = 0;\n var str = [ ];\n var source = paramSourceString.toLowerCase( );\n for( var i = 0; i < digits; i++ ) {\n var charCode = source.charCodeAt( paramOffset + i );\n result = result << 4;\n if (charCode > 47 && charCode < 58) {\n result = result | ( charCode - 48 );\n }\n else {\n result = result | ( charCode - 55 );\n }\n if( i > 0 && i % 2 == 0 ) {\n str.push( String.fromCharCode( result ) );\n result = 0;\n }\n }\n if( i > 0 && i % 2 == 0 ) {\n str.push( String.fromCharCode( result ) );\n }\n return str.join( "" );\n}\n\nconfig.macros.binaryData.readFloat = function( paramSourceString, paramOffset ) {\n var result = 0;\n var charCodes = [\n paramSourceString.charCodeAt( paramOffset ),\n paramSourceString.charCodeAt( paramOffset + 1 ),\n paramSourceString.charCodeAt( paramOffset + 2 ),\n paramSourceString.charCodeAt( paramOffset + 3 )\n ];\n var negative = ( charCodes [ 0 ] & 128 ) != 0;\n var exponent = ( ( charCodes [ 0 ] & 127 << 1 ) | ( charCodes [ 1 ] & 128 ) ) - 127;\n var zeroMantissa = ( charCodes [ 1 ] & 127 ) == charCodes [ 2 ] == charCodes [ 3 ] == 0;\n if ( exponent == 255 ) {\n if ( zeroMantissa ) {\n return Infinity;\n }\n else {\n return NaN;\n }\n }\n else if ( exponent == 0 ) {\n if ( zeroMantissa ) {\n return 0;\n }\n else {\n //Denormalized Number\n return Math.pow( 2, -149 ) *\n ( ( ( ( ( charCodes [ 1 ] & 127 ) << 8 ) | charCodes [ 2 ] ) << 8 ) | charCodes [ 3 ] ) *\n ( negative ? -1 : 1 );\n }\n }\n else {\n return Math.pow( 2, exponent - 23 ) *\n ( ( ( ( 128 | ( charCodes [ 1 ] & 127 ) << 8 ) | charCodes [ 2 ] ) << 8 ) | charCodes [ 3 ] ) *\n ( negative ? -1 : 1 );\n }\n}\n\nconfig.macros.binaryData.readStringFromString = function( paramSourceString, paramOffset ) {\n var charCode = paramSourceString.charCodeAt( paramOffset );\n var offset = 1;\n var result = [ ];\n while( charCode != 0) {\n result.push( String.fromCharCode( charCode ) );\n charCode = paramSourceString.charCodeAt( paramOffset + ( offset++ ) );\n }\n return result.join( "" );\n}\n\nconfig.macros.binaryData.readCharFromString = function( paramSourceString, paramOffset ) {\n return paramSourceString.charCodeAt( paramOffset );\n}\n\nconfig.macros.binaryData.readShortFromString = function( paramSourceString, paramOffset ) {\n var result = paramSourceString.charCodeAt( paramOffset );\n result = result << 8;\n return ( result + paramSourceString.charCodeAt( paramOffset + 1 ) );\n}\n\nconfig.macros.binaryData.readIntFromString = function( paramSourceString, paramOffset ) {\n var result = paramSourceString.charCodeAt( paramOffset );\n result = result << 8;\n result += paramSourceString.charCodeAt( paramOffset + 1);\n result = result << 8;\n result += paramSourceString.charCodeAt( paramOffset + 2);\n result = result << 8;\n return ( result + paramSourceString.charCodeAt( paramOffset + 3 ) );\n}\n\nconfig.macros.binaryData.readDataFromString = function( paramSourceString, paramOffset, paramDataTypeString ) {\n \n};\n\nconfig.macros.binaryData.writeChar = function( paramSourceNumber ) {\n return String.fromCharCode( paramSourceNumber );\n}\n\nconfig.macros.binaryData.writeShort = function( paramSourceNumber ) {\n return String.fromCharCode( paramSourceNumber >> 8 & 255 ) +\n String.fromCharCode( paramSourceNumber & 255 );\n}\n\nconfig.macros.binaryData.writeInt = function( paramSourceNumber ) {\n return String.fromCharCode( paramSourceNumber >> 24 & 255 ) +\n String.fromCharCode( paramSourceNumber >> 16 & 255 ) +\n String.fromCharCode( paramSourceNumber >> 8 & 255 ) +\n String.fromCharCode( paramSourceNumber & 255 );\n}\n\nconfig.macros.binaryData.writeString = function( paramSourceString ) {\n return paramSourceString + String.fromCharCode( 0 );\n}\n\nconfig.macros.binaryData.getStringFromData = function( paramDataTypeString ) {\n var result = [];\n return result.join( "" );\n}\n//}}}
/***\n| Name:|CaptureKeysMacro|\n| Purpose:|Makes an easy way to capture a key and stop the browser from doing its default action|\n| Creator:|BradleyMeck|\n| Ideas:|BradleyMeck & SaqImtiaz|\n| Source:|http://tiddlyspot.com/BradleyMeck/#CaptureKeysMacro|\n| Requires:|Javascript|\n| Version|1.0 (July 24, 2006)|\n\n!History\n** First release\n!Usage\nconfig.macros.captureKey(object,handler,keyCode,SHIFT,ALT,CTRL);\n|''object''|Where (element, document, etc.) to try to capture the event at (useful because of stopPropagation).|\n|''handler''|Function to execute when this key is captured.|\n|''keyCode''|The keyCode to execute this function if this key is depressed.|\n|''SHIFT''|Should the Shift key be depressed when this event occurs?|\n|''ALT''|Should the Alt key be depressed when this event occurs?|\n|''CTRL''|Should the Ctrl key be depressed when this event occurs?|\n!Notes\n|If something changes the element's onkeydown/press handlers and the browser does not support addEventListener or attachEvent, the key capturing will be ruined.|\n|Please use the removeCaptureKey function to remove the capture keys if you dont want them to occur anymore, please? However, removing the 'F1' key does not make onhelp work again.|\n|config.macros.captureKeys.preventDefault(), config.macros.captureKeys.stopPropagation(), config.macros.captureKeys.getRealKey(event) are good functions to use in other plugins as well|\n!Examples\nFor 'CTRL'+'S' Saving\n{{{\nconfig.macros.captureKeys.captureKey(document,saveChanges,"S",false,false,true);\n}}}\n!Code\n!!!Virtual Keyboard\n***/\n//{{{\nconfig.macros.captureKeys = {};\nconfig.macros.captureKeys.VK = {\n/*KEYS ARE MAPPED FROM TOP LEFT TO BOTTOM RIGHT,\nTHE NAMES ARE TAKEN FROM THE JAVA VK*/\n "ESCAPE": 27,\n "F1": 112,\n "F2": 113,\n "F3": 114,\n "F4": 115,\n "F5": 116,\n "F6": 117,\n "F7": 118,\n "F8": 119,\n "F9": 120,\n "F10": 121,\n "F11": 122,\n "F12": 123,\n "PRINT_SCREEN": 44,\n "SCROLL_LOCK": 145,\n "PAUSE": 19,\n "BACK_QUOTE": 192,\n "1": 49,\n "2": 50,\n "3": 51,\n "4": 52,\n "5": 53,\n "6": 54,\n "7": 55,\n "8": 56,\n "9": 57,\n "0": 48,\n "MINUS": 109,\n "EQUALS": 61,\n "BACKSPACE": 8,\n "INSERT": 45,\n "HOME": 36,\n "PAGE_UP": 33,\n "NUM_LOCK": 144,\n "NUMPADDIVIDE": 111,\n "MULTIPLY": 106,\n "NUMPADMINUS": 109,\n "TAB": 9,\n "Q": 81,\n "W": 87,\n "E": 69,\n "R": 82,\n "T": 84,\n "Y": 89,\n "U": 85,\n "I": 73,\n "O": 79,\n "P": 80,\n "OPEN_BRACKET": 219,\n "CLOSE_BRACKET": 221,\n "BACK_SLASH": 220,\n "DELETE": 46,\n "END": 35,\n "PAGE_DOWN": 34,\n "NUMPAD7": 103,\n "NUMPAD8": 104,\n "NUMPAD9": 105,\n "PLUS": 107,\n "CAPS_LOCK": 20,\n "A": 65,\n "S": 83,\n "D": 68,\n "F": 70,\n "G": 71,\n "H": 72,\n "J": 74,\n "K": 75,\n "L": 76,\n "SEMICOLON": 59,\n "QUOTE": 222,\n "ENTER": 13,\n "NUMPAD4": 100,\n "NUMPAD5": 101,\n "NUMPAD6": 102,\n "SHIFT": 16,\n "Z": 90,\n "X": 88,\n "C": 67,\n "V": 86,\n "B": 66,\n "N": 78,\n "M": 77,\n "COMMA": 188,\n "PERIOD": 190,\n "DIVIDE": 191,\n "UP": 38,\n "NUMPAD1": 97,\n "NUMPAD2": 98,\n "NUMPAD3": 99,\n "CONTROL": 17,\n "ALT": 18,\n "SPACE": 32,\n "LEFT": 37,\n "DOWN": 40,\n "RIGHT": 39,\n "NUMPAD0": 96,\n "NUMPADPERIOD": 110\n}\nconfig.macros.captureKeys.UNICodeToAsciiVK = \n{\n 33 : 49,\n 34 : 222,\n 35 : 51,\n 36 : 52,\n 37 : 53,\n 38 : 55,\n 39 : 222,\n 40 : 57,\n 41 : 48,\n 42 : 56,\n 43 : 61,\n 44 :188,\n 45 :109,\n 46 :190,\n 47 :191,\n 48 : 96,\n 49 : 97,\n 50 : 98,\n 51 : 99,\n 52 :100,\n 53 :101,\n 54 :102,\n 55 :103,\n 56 :104,\n 57 :105,\n 58 : 59,\n 60 :188,\n 62 :190,\n 63 :191,\n 64 : 50,\n 91 :219,\n 92 :220,\n 93 :221,\n 94 : 54,\n 95 :109,\n 96 :192, \n 97 : 65,\n 98 : 66,\n 99 : 67,\n 100: 68,\n 101: 69,\n 102: 70,\n 103: 71,\n 104: 72,\n 105: 73,\n 106: 74,\n 107: 75,\n 108: 76,\n 109: 77,\n 110: 78,\n 111: 79,\n 112: 80,\n 113: 81,\n 114: 82,\n 115: 83,\n 116: 84,\n 117: 85,\n 118: 86,\n 119: 87,\n 120: 88,\n 121: 89,\n 122: 90,\n 123:219,\n 124:220,\n 125:221,\n 126:192\n}\n//}}}\n/***\n!!!!captureKey function\n***/\n//{{{\nwindow.captureKey = config.macros.captureKeys.captureKey = function(elem,handler,keyCode,shiftButton,altButton,ctrlButton)\n{\n if(!elem.captureKeys)\n {\n elem.captureKeys = [];\n }\n var keyEvent = {};\n keyEvent.key = config.macros.captureKeys.VK[keyCode]?config.macros.captureKeys.VK[keyCode]:keyCode;\n keyEvent.shift = shiftButton;\n keyEvent.alt = altButton;\n keyEvent.ctrl = ctrlButton;\n keyEvent.func = handler; \n elem.captureKeys.push(keyEvent);\n // IE needs onkeyDown\n // moz needs onkeypress\n if(window.event)\n {\n // For some reason cancelling the f1 keypress doesnt stop it from loading the help?\n if(keyCode == 112){document.onhelp = function(event){if(!event)var event=window.event;config.macros.captureKeys.preventDefault(event)}}\n if(!config.macros.captureKeys.hasEventListener(elem,"keydown",config.macros.captureKeys.captureKeyHandler)){\n config.macros.captureKeys.addEventListener(elem,"keydown",config.macros.captureKeys.captureKeyHandler);}\n }\n else\n {\n if(!config.macros.captureKeys.hasEventListener(elem,"keypress",config.macros.captureKeys.captureKeyHandler))\n config.macros.captureKeys.addEventListener(elem,"keypress",config.macros.captureKeys.captureKeyHandler); \n }\n return keyEvent;\n}\nconfig.macros.captureKeys.captureKeyHandler = function(event)\n{\n if(!this.captureKeys)return null;\nvar keyCode = config.macros.captureKeys.getRealKey(event)\n for(var i = 0; i < this.captureKeys.length; i++)\n {\n if(this.captureKeys[i].key == keyCode && this.captureKeys[i].shift == event.shiftKey && this.captureKeys[i].alt == event.altKey && this.captureKeys[i].ctrl == event.ctrlKey)\n {\n this.captureKeys[i].func.call(this,event);\n config.macros.captureKeys.preventDefault(event);\n }\n }\n}\nconfig.macros.captureKeys.getRealKey = function(event)\n{\nvar keyCode = event.keyCode;\nif(!keyCode || (keyCode && keyCode == 0))\n{\n var unicode=event.which? event.which: event.charCode;\n keyCode = (config.macros.captureKeys.UNICodeToAsciiVK[unicode]?config.macros.captureKeys.UNICodeToAsciiVK[unicode]:unicode);\n}\nreturn keyCode;\n}\nconfig.macros.captureKeys.removeCaptureKey = function(elem,handler,keyCode,shiftButton,altButton,ctrlButton)\n{\n if(!elem.captureKeys)return null;\n for(var i = 0; i < elem.captureKeys.length; i++)\n {\n if(elem.captureKeys[i].key == keyCode && elem.captureKeys[i].shift == shiftButton && elem.captureKeys[i].alt == altButton && elem.captureKeys[i].ctrl == ctrlButton && elem.captureKeys[i].func == handler)\n {\n if(!elem.captureKeys || (elem.captureKeys && elem.captureKeys.length == 1))\n {\n elem.captureKeys = null;\n config.macros.captureKeys.removeEventListener(elem,window.event?"keydown":"keypress",config.macros.captureKeys.captureKeyHandler);\n return false;\n }\n else\n {\n elem.captureKeys.splice(i,1)\n }\n }\n }\n}\nconfig.macros.captureKeys.addEventListener = function(target,eventType,func,capturing)\n{\n if(!target.eventListeners)\n {\n target.eventListeners = {};\n }\n if(!target.eventListeners[eventType])\n {\n target.eventListeners[eventType] = [];\n }\n if(target.addEventListener)\n {\n target.addEventListener(eventType,func,capturing);\n target.eventListeners[eventType].push(func);\n return func;\n }\n else if(target.attachEvent)\n {\n var handler = function(event)\n {\n if(!event)var event = window.event;\n func.call(target,event);\n };\n handler.originalFunction = func;\n target.attachEvent("on"+eventType,handler);\n target.eventListeners[eventType].push(handler);\n return handler;\n }\n else\n {\n if(target.eventListeners[eventType].length == 0)\n {\n if(target["on"+eventType])\n {\n target.eventListeners[eventType].push(target["on"+eventType]);\n }\n target["on"+eventType] = api.event.standardEventHandler;\n }\n target.eventListeners[eventType].push(func);\n }\n}\nconfig.macros.captureKeys.standardEventHandler = function(event)\n{\n if(!event)var event = window.event;\n if(!this.eventListeners || !this.eventListeners[event.type])return null;\n for(var i = 0; i < this.eventListeners[event.type].length; i++)\n {\n this.eventListeners[event.type][i].call(this,event);\n }\n}\nconfig.macros.captureKeys.removeEventListener = function(target,eventType,func,capturing)\n{\n if(!target.eventListeners || !target.eventListeners[eventType])\n {\n return null;\n }\n if(target.removeEventListener)\n {\n target.removeEventListener(eventType,func,capturing);\n target.eventListeners[eventType].splice(target.eventListeners[eventType].indexOf(func),1);\n }\n else if(target.detachEvent)\n {\n var trueFunc = null;\n var i = 0;\n for(; i < target.eventListeners.length; i++)\n {\n if(target.eventListeners[i].originalFunction = func)\n {\n trueFunc = target.eventListeners[i];\n break;\n }\n }\n if(trueFunc)\n {\n target.detachEvent("on"+eventType,trueFunc);\n target.eventListeners[eventType].splice(i,1);\n }\n }\n else\n {\n target.eventListeners[eventType].splice(target.eventListeners[eventType].indexOf(func),1);\n if(target.eventListeners[eventType].length == 0)target["on"+eventType] = null;\n }\n if(target.eventListeners[eventType].length == 0)\n {\n delete target.eventListeners[eventType];\n }\n for(var i in target.eventListeners)\n {\n return;\n }\n target.eventListeners = undefined;\n}\nconfig.macros.captureKeys.hasEventListener = function(elem,eventType,func)\n{\n if(!elem.eventListeners || !elem.eventListeners[eventType]) return false;\n if(elem.eventListeners[eventType].indexOf(func)!=null)return true;\n return false;\n}\nconfig.macros.captureKeys.preventDefault = function(event){\n try\n {\n event.keyCode = 0; // Kills old IE\n }\n catch(exeption)\n {\n }\n if(window.event)\n {\n event.returnValue=false;\n }\n if(event.preventDefault)\n {\n event.preventDefault();\n }\n return event;\n}\n\nconfig.macros.captureKeys.stopPropagation = function(event){\n if(event.cancelBubble)\n {\n event.cancelBubble=false;\n }\n if(event.stopPropagation)\n {\n event.stopPropagation();\n }\n return event;\n}\n//}}}
/***\n!CTRL+S\nSaving\n***/\n//{{{\nif(location.href.indexOf("file://")==0){window.captureKey(document,saveChanges,"S",false,false,true);}\nif(location.href.indexOf("http://")==0)window.captureKey(document,function()\n{\nconfig.macros.upload.upload("http://bradleymeck.tiddlyspot.com/store.php", "index.html", ".", ".", "BradleyMeck")\n},"S",false,false,true);\n//}}}
/***\n!About\n|Author: Bradley Meck|\n|Date: Dec 20, 2006|\n|Version: 1.0.0|\nThis object the DOMCrawler is made to simplify crawling through the DOM trying to find a node. Since it can ofter be confusing to write code that does this as well as what you may be testing for this seems like the best route to take by making an iterator to do it for you.\n\nAlso since there can be a hassle jumping in and out of nodes to accomplish some tasks going forward and backward, this object might help you out.\n\n!Example Usage\n!!!Find First Text Node From A Node And Remove it\n{{{\n\nvar startNode = element;\nvar crawler = new DOMCrawler(startNode)\nwhile(crawler.currentNode.nodeType != 3)crawler.getNextNode();\n//If a textNode was found and it has a parent\nif(crawler.currentNode && crawler.currentNode.parentNode){\n crawler.currentNode.parentNode.removeChild(crawler.currentNode);\n}\n\n}}}\n!Code\n***/\n//{{{\nconfig.macros.DOMCrawler = function(startNode){\n this.currentNode = startNode;\n this.state = -1;\n this.lastMovement = STAYED;\n this.STAYED = -1;\n this.JUMP_OUT = 0;\n this.JUMP_IN = 1;\n this.ADJACENT_NODE = 2;\n}\n\nconfig.macros.DOMCrawler.prototype = {\n getNextNode: function(){\n if(this.currentNode.childNodes && this.currentNode.childNodes.length > 0){\n this.currentNode = this.currentNode.firstChild;\n this.state = this.JUMP_IN\n }\n else if(this.currentNode.nextSibling){\n this.currentNode = this.currentNode.nextSibling;\n this.state = this.ADJACENT_NODE;\n }\n else{\n if(this.currentNode.parentNode && this.currentNode.parentNode.nextSibling){\n this.currentNode = this.currentNode.parentNode.nextSibling;\n }\n else{\n this.lastMovement = this.STAYED;\n return;\n }\n this.state = this.JUMP_OUT;\n }\n this.lastMovement = 1;\n },\n getNextInternalNode: function(){\n if(this.currentNode.childNodes && this.currentNode.childNodes.length > 0){\n this.currentNode = this.currentNode.firstChild;\n this.state = this.JUMP_IN\n }\n else if(this.currentNode.nextSibling){\n this.currentNode = this.currentNode.nextSibling;\n this.state = this.ADJACENT_NODE;\n }\n else{\n this.lastMovement = this.STAYED;\n return;\n }\n this.lastMovement = 1;\n },\n getNextOuterNode: function(){\n if(this.currentNode.nextSibling){\n this.currentNode = this.currentNode.nextSibling;\n this.state = this.ADJACENT_NODE;\n }\n else{\n if(this.currentNode.parentNode && this.currentNode.parentNode.nextSibling){\n this.currentNode = this.currentNode.parentNode.nextSibling;\n }\n else{\n this.lastMovement = this.STAYED;\n return;\n }\n this.state = this.JUMP_OUT;\n }\n this.lastMovement = 1;\n },\n getPreviousNode: function(){\n if(this.currentNode.childNodes && this.currentNode.childNodes.length > 0){\n this.currentNode = this.currentNode.lastChild;\n this.state = this.JUMP_IN\n }\n else if(this.currentNode.previousSibling){\n this.currentNode = this.currentNode.previousSibling;\n this.state = this.ADJACENT_NODE;\n }\n else{\n if(this.currentNode.parentNode && this.currentNode.parentNode.previousSibling){\n this.currentNode = this.currentNode.parentNode.previousSibling;\n }\n else{\n this.lastMovement = this.STAYED;\n return;\n }\n this.state = this.JUMP_OUT;\n }\n this.lastMovement = -1;\n },\n getPreviousInternalNode: function(){\n if(this.currentNode.childNodes && this.currentNode.childNodes.length > 0){\n this.currentNode = this.currentNode.lastChild;\n this.state = this.JUMP_IN\n }\n else if(this.currentNode.previousSibling){\n this.currentNode = this.currentNode.previousSibling;\n this.state = this.ADJACENT_NODE;\n }\n else{\n this.lastMovement = this.STAYED;\n return;\n }\n this.lastMovement = -1;\n },\n getPreviousOuterNode: function(){\n if(this.currentNode.previousSibling){\n this.currentNode = this.currentNode.previousSibling;\n this.state = this.ADJACENT_NODE;\n }\n else{\n if(this.currentNode.parentNode && this.currentNode.parentNode.previousSibling){\n this.currentNode = this.currentNode.parentNode.previousSibling;\n }\n else{\n this.lastMovement = this.STAYED;\n return;\n }\n this.state = this.JUMP_OUT;\n }\n this.lastMovement = -1;\n }\n}\n//}}}
[[26 January 2007]]
/***\n!About\n|Author: Bradley Meck|\n|Date: Dec 24, 2006|\n|Version: 1.4.1|\nThis is a simple function to be used to find the differences between one set of objects and another. ''The objects do not need to be Strings''. It outputs and array of objects with the properties value and change. This function is pretty hefts but appears to be rather light for a diff and tops out at O(N^^2^^) for absolute worst cast scenario that I can find.\n!History\n*December 23, 2006 - Function made to be minimal edit diff, and changed output.\n!Code\n***/\n//{{{\nfunction diff( oldArray, newArray ) {\n var newElementHash = { };\n for( var i = 0; i < newArray.length; i++ ) {\n if( ! newElementHash [ newArray [ i ] ] ) {\n newElementHash [ newArray [ i ] ] = [ ];\n }\n newElementHash [ newArray [ i ] ].push( i );\n }\n var substringTable = [ ];\n for( var i = 0; i < oldArray.length; i++ ) {\n if(newElementHash [ oldArray [ i ] ] ) {\n var locations = newElementHash [ oldArray [ i ] ] ;\n for( var j = 0; j < locations.length; j++){\n var length = 1;\n while( i + length < oldArray.length && locations [ j ] + length < newArray.length\n && oldArray [ i + length ] == newArray [ locations [ j ] + length ] ){\n length++;\n }\n substringTable.push( {\n oldArrayIndex : i,\n newArrayIndex : locations [ j ],\n matchLength : length\n } );\n }\n }\n }\n substringTable.sort( function( a, b ) {\n if ( a.matchLength > b.matchLength /* a is less than b by some ordering criterion */ ) {\n return -1;\n }\n if ( a.matchLength < b.matchLength /* a is greater than b by the ordering criterion */ ) {\n return 1;\n }\n // a must be equal to b\n return 0\n } );\n //displayMessage( substringTable.toSource( ) );\n for( var i = 0; i < substringTable.length; i++) {\n for( var j = 0; j < i; j++) {\n var oldDelta = substringTable [ i ].oldArrayIndex + substringTable [ i ].matchLength - 1 - substringTable [ j ].oldArrayIndex;\n var newDelta = substringTable [ i ].newArrayIndex + substringTable [ i ].matchLength - 1 - substringTable [ j ].newArrayIndex;\n //displayMessage( "oldDelta ::: " + oldDelta );\n //displayMessage( "newDelta ::: " + newDelta );\n //displayMessage( "matchLength ::: " + substringTable [ j ].matchLength );\n if( ( oldDelta >= 0 && oldDelta <= substringTable [ j ].matchLength )\n || ( newDelta >= 0 && newDelta <= substringTable [ j ].matchLength )\n || ( oldDelta < 0 && newDelta > 0 )\n || ( oldDelta > 0 && newDelta < 0 ) ) {\n substringTable.splice( i, 1 );\n i--;\n break;\n }\n }\n }\n //displayMessage( substringTable.toSource( ) );\n substringTable.sort( function( a, b ) {\n if ( a.oldArrayIndex < b.oldArrayIndex /* a is less than b by some ordering criterion */ ) {\n return -1;\n }\n if ( a.oldArrayIndex > b.oldArrayIndex /* a is greater than b by the ordering criterion */ ) {\n return 1;\n }\n // a must be equal to b\n return 0\n } );\n //displayMessage( substringTable.toSource( ) );\n var oldArrayIndex = 0;\n var newArrayIndex = 0;\n var results = [ ];\n for( var i = 0; i < substringTable.length; i++ ) {\n if( oldArrayIndex != substringTable [ i ].oldArrayIndex ) {\n results.push( {\n change : "DELETED",\n length : substringTable [ i ].oldArrayIndex - oldArrayIndex,\n index : oldArrayIndex\n } );\n }\n if( newArrayIndex != substringTable [ i ].newArrayIndex ) {\n results.push( {\n change : "ADDED",\n length : substringTable [ i ].newArrayIndex - newArrayIndex,\n index : newArrayIndex\n } );\n }\n results.push( {\n change : "STAYED",\n length : substringTable [ i ].matchLength,\n index : substringTable [ i ].oldArrayIndex\n } );\n oldArrayIndex = substringTable [ i ].oldArrayIndex + substringTable [ i ].matchLength;\n newArrayIndex = substringTable [ i ].newArrayIndex + substringTable [ i ].matchLength;\n }\n if( oldArrayIndex != oldArray.length ) {\n results.push( {\n change : "DELETED",\n length : oldArray.length - oldArrayIndex,\n index : oldArrayIndex\n } );\n }\n if( newArrayIndex != newArray.length ) {\n results.push( {\n change : "ADDED",\n length : newArray.length - newArrayIndex,\n index : newArrayIndex\n } );\n }\n return results;\n}\n//}}}\n
<!---\n| Name:|~TagglyTaggingEditTemplate |\n| Version:|1.1 (12-Jan-2006)|\n| Source:|http://simonbaird.com/mptw/#TagglyTaggingEditTemplate|\n| Purpose:|See TagglyTagging for more info|\n| Requires:|You need the CSS in TagglyTaggingStyles to make it look right|\n--->\n<!--{{{-->\n<div class="title" macro="view title"></div>\n<div class="toolbar" macro="toolbar +saveTiddler closeOthers cancelTiddler deleteTiddler"></div>\n<div class="editLabel">Title</div><div class="editor" macro="edit title"></div>\n<div class="editLabel">Tags</div><div class="editor" macro="edit tags"></div>\n<div class="editorFooter"><span macro="message views.editor.tagPrompt"></span><span macro="tagChooser systemConfig"></span></div>\n<div class="editor" macro="edit text"></div>\n<br/>\n<!--}}}-->
/***\n|FileDropPlugin|h\n|author : BradleyMeck|\n|version : 0.1.1|\n|date : Nov 13 2006|\n|usage : drag a file onto the TW to have it be made into a tiddler|\n|browser(s) supported : Mozilla|\n\n!Trouble Shooting\n*If the plugin does not seem to work, open up the page "about:config" (just type it in the address bar) and make sure @@color(blue):signed.applets.codebase_principal_support@@ is set to @@color(blue):true@@\n\n!Revisions\n*Multiple File Dropping API updated, to end all capturing events after yours return a value that makes if(myFunctionsReturnValue) evaluate to true\n*Added support for multiple file drop handlers\n**Use the config.macros.fileDrop.addEventListener(@@color(green):String Flavor@@, @@color(green):Function handler(nsiFile){}@@, @@color(green):Boolean addToFront@@) function\n***Standard Flavor is "application/x-moz-file"\n***addToFront gives your handler priority over all others at time of add\n*Old plugin would disallow drops of text vetween applications because it didn't check if the transfer was a file.\n\n!Example Handler\n*Adds simple file import control, add this to a tiddler tagged {{{systemConfig}}} to make file dropping work\n{{{\nconfig.macros.fileDrop.addEventListener("application/x-moz-file",function(nsiFile)\n{\n if(\n confirm("You have dropped the file \s""+nsiFile.path+"\s" onto the page, it will be imported as a tiddler. Is that ok?")\n )\n {\n var newDate = new Date();\n var title = prompt("what would you like to name the tiddler?");\n store.saveTiddler(title,title,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);\n }\n return true;\n})\n}}}\n\n!Example Handler without popups and opening the tiddler on load\n*Adds simple file import control, add this to a tiddler tagged {{{systemConfig}}} to make file dropping work\n{{{\nconfig.macros.fileDrop.addEventListener("application/x-moz-file",function(nsiFile)\n{\n var newDate = new Date();\n store.saveTiddler(nsiFile.path,nsiFile.path,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);\n story.displayTiddler(null,nsiFile.path)\n return true;\n})\n}}}\n\n***/\n\n//{{{\nconfig.macros.fileDrop = {varsion : {major : 0, minor : 0, revision: 1}};\nconfig.macros.fileDrop.customDropHandlers = [];\n\nconfig.macros.fileDrop.dragDropHandler = function(evt) {\n\n netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');\n // Load in the native DragService manager from the browser.\n var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);\n\n // Load in the currently-executing Drag/drop session.\n var dragSession = dragService.getCurrentSession();\n\n // Create an instance of an nsITransferable object using reflection.\n var transferObject = Components.classes["@mozilla.org/widget/transferable;1"].createInstance();\n\n // Bind the object explicitly to the nsITransferable interface. We need to do this to ensure that\n // methods and properties are present and work as expected later on.\n transferObject = transferObject.QueryInterface(Components.interfaces.nsITransferable);\n\n // I've chosen to add only the x-moz-file MIME type. Any type can be added, and the data for that format\n // will be retrieved from the Drag/drop service.\n transferObject.addDataFlavor("application/x-moz-file");\n\n // Get the number of items currently being dropped in this drag/drop operation.\n var numItems = dragSession.numDropItems;\n for (var i = 0; i < numItems; i++)\n {\n // Get the data for the given drag item from the drag session into our prepared\n // Transfer object.\n dragSession.getData(transferObject, i);\n\n // We need to pass in Javascript 'Object's to any XPConnect method which\n // requires OUT parameters. The out value will then be saved as a new\n // property called Object.value.\n var dataObj = {};\n var dropSizeObj = {};\n\nfor(var ind = 0; ind < config.macros.fileDrop.customDropHandlers.length; ind++)\n{\n var item = config.macros.fileDrop.customDropHandlers[ind];\n if(dragSession.isDataFlavorSupported(item.flavor))\n {\n transferObject.getTransferData(item.flavor, dataObj, dropSizeObj);\n var droppedFile = dataObj.value.QueryInterface(Components.interfaces.nsIFile);\n // Display all of the returned parameters with an Alert dialog.\n var result = item.handler.call(item,droppedFile);\n // Since the event is handled, prevent it from going to a higher-level event handler.\n evt.stopPropagation();\n evt.preventDefault();\n if(result){break;}\n }\n}\n }\n}\n\nif(!window.event)\n{\n // Register the event handler, and set the 'capture' flag to true so we get this event\n // before it bubbles up through the browser.\n window.addEventListener("dragdrop", config.macros.fileDrop.dragDropHandler , true);\n}\n\nconfig.macros.fileDrop.addEventListener = function(paramflavor,func,inFront)\n{\nvar obj = {};\nobj.flavor = paramflavor;\nobj.handler = func;\nif(!inFront)\n{config.macros.fileDrop.customDropHandlers.push(obj);}\nelse{config.macros.fileDrop.customDropHandlers.shift(obj);}\n}\n//}}}
config.macros.fileDrop.addEventListener("application/x-moz-file",function(nsiFile)\n{\n var newDate = new Date();\n store.saveTiddler(null,nsiFile.path,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);\n story.displayTiddler(null,nsiFile.path)\n})
!''Welcome to the ~PeachTW''\nHere you will find many features being developed for people who need some programming done in Javascript, this could be any sort of feature, but most prominent are UI features, File features, and creating an API that works when you want to program something.\n<<<\n!!!//About Me//\nI am a college student trying to make it as a computer science major. I live in Austin, Texas happily with the most endearing girl I have ever met as my girlfriend.\n!!!//Interests in Programming//\nText algorithms and patterns are my real joy but I am also interested in the user interface of computers and providing easy to use interfaces to people if you couldn't get it from my minimalist site here.\n!!!//Licensing//\nTake it, put my name some where, you are good to go.\n!!!//~E-Mail//\nGenisis329 at gmail dot com\n!!!//Requests//\nGot a suggestion or request, go to [[TiddlyWikiRequests|http://groups.google.com/group/TiddlyWikiRequests]]\n<<<
/***\n!HelloWorld Macro\nAlways include Author, Source,and Version in a table so that people know what they have.\n|Author: Simon Baird|\n|Documentation: Bradley Meck|\n|Source: http://bradleymeck.tiddlyspot.com/#HelloWorld|\n|Version: 1.0.0|\n\n!Revisions\n*10/29/2006 Added documentation to make this more understandable for plugin developers\n\n!example\n|Source|Output|\n|{{{<<HelloWorld>>}}}|<<HelloWorld>>|\n|{{{<<HelloWorld "I am" "the params.">>}}}|<<HelloWorld "I am" "the params.">>|\n***/\n//{{{\nconfig.macros.HelloWorld = {}; //config.macros["Name of my Macro"]\n\n/**\n* handler is called by TW when the macro is seen.\n* its arguements are as follows\n* place: DOM element where the macro's source was found. (Usually just put stuff here with createTiddlyElement(place,...)).\n* macroName: what the macro is called, can be good if macros call each other for some reason.\n* params: list of parameters given from the macro source, as an Array\n* wikifier: the wikifier that sent this call\n* paramString: unparsed version of params as a String\n* tiddler: the tiddler that this macro is being called in\n**/\n\nconfig.macros.HelloWorld.handler =\nfunction(place,macroName,params,wikifier,paramString,tiddler)\n{\n wikify("Hello World <br>"+params.join("<br>"),place);\n};\n\n//}}}\n
/***\nTo use, add {{{[[HorizontalMainMenuStyles]]}}} to your StyleSheet tiddler, or you can just paste the CSS in directly. See also HorizontalMainMenu and PageTemplate.\n***/\n/*{{{*/\n\n#topMenu br {display:none; }\n#topMenu { background-color: #fff; padding:2px; color: #8af;}\n#topMenu .button, #topMenu .tiddlyLink {\n margin-left:0.5em; margin-right:0.5em;\n padding-left:3px; padding-right:3px;\n font-size:115%;\n}\n#topMenu .button:hover, #topMenu .tiddlyLink:hover { background:#8af; color: white;}\n\n#displayArea { margin: 1em 15.7em 0em 1em; } /* so we use the freed up space */\n\n/* just in case want some QuickOpenTags in your topMenu */\n#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }\n#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }\n#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }\n\n\n/*}}}*/
/***\n|''Name:''|InlineJavascriptPlugin|\n|''Source:''|http://www.TiddlyTools.com/#InlineJavascriptPlugin|\n|''Author:''|Eric Shulman - ELS Design Studios|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|''~CoreVersion:''|2.0.10|\n\nInsert Javascript executable code directly into your tiddler content. Lets you ''call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.\n!!!!!Usage\n<<<\nWhen installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.\n\n''Deferred execution from an 'onClick' link''\nBy including a label="..." parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.\n\n''External script source files:''\nYou can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.\n\n''Display script source in tiddler output''\nBy including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.\n\n''Defining javascript functions and libraries:''\nAlthough the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).\n\nTo ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.\n\nSince the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.\n\n''Creating dynamic tiddler content''\nAn important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:\n* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.\n* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.\n* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.\n\nIf your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.\n\n//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//\n\n''Accessing the ~TiddlyWiki DOM''\nThe plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.\n\nAccess to this DOM element allows you to create scripts that can:\n* vary their actions based upon the specific location in which they are embedded\n* access 'tiddler-relative' information (use findContainingTiddler(place))\n* perform direct DOM manipulations (when returning wikified text is not enough)\n<<<\n!!!!!Examples\n<<<\nan "alert" message box:\n><script show>\n alert('InlineJavascriptPlugin: this is a demonstration message');\n</script>\ndynamic output:\n><script show>\n return (new Date()).toString();\n</script>\nwikified dynamic output:\n><script show>\n return "link to current user: [["+config.options.txtUserName+"]]";\n</script>\ndynamic output using 'place' to get size information for current tiddler:\n><script show>\n if (!window.story) window.story=window;\n var title=story.findContainingTiddler(place).id.substr(7);\n return title+" is using "+store.getTiddlerText(title).length+" bytes";\n</script>\ncreating an 'onclick' button/link that runs a script:\n><script label="click here" show>\n if (!window.story) window.story=window;\n alert("Hello World!\snlinktext='"+place.firstChild.data+"'\sntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");\n</script>\nloading a script from a source url:\n>http://www.TiddlyTools.com/demo.js contains:\n>>{{{function demo() { alert('this output is from demo(), defined in demo.js') } }}}\n>>{{{alert('InlineJavascriptPlugin: demo.js has been loaded'); }}}\n><script src="demo.js" show>\n return "loading demo.js..."\n</script>\n><script label="click to execute demo() function" show>\n demo()\n</script>\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2006.10.16 [1.5.2]'' add newline before closing '}' in 'function out_' wrapper. Fixes error caused when last line of script is a comment.\n''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly\n''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output\n''2006.01.05 [1.4.0]'' added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.\n''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski\n''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content. Based on a suggestion by BradleyMeck\n''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax\n''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access \n''2005.11.08 [1.0.0]'' initial release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.inlineJavascript= {major: 1, minor: 5, revision: 2, date: new Date(2006,10,16)};\n\nconfig.formatters.push( {\n name: "inlineJavascript",\n match: "\s\s<script",\n lookahead: "\s\s<script(?: src=\s\s\s"((?:.|\s\sn)*?)\s\s\s")?(?: label=\s\s\s"((?:.|\s\sn)*?)\s\s\s")?( show)?\s\s>((?:.|\s\sn)*?)\s\s</script\s\s>",\n\n handler: function(w) {\n var 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 if (lookaheadMatch[1]) { // load a script library\n // make script tag, set src, add to body to execute, then remove for cleanup\n var script = document.createElement("script"); script.src = lookaheadMatch[1];\n document.body.appendChild(script); document.body.removeChild(script);\n }\n if (lookaheadMatch[4]) { // there is script code\n if (lookaheadMatch[3]) // show inline script code in tiddler output\n wikify("{{{\sn"+lookaheadMatch[0]+"\sn}}}\sn",w.output);\n if (lookaheadMatch[2]) { // create a link to an 'onclick' script\n // add a link, define click handler, save code in link (pass 'place'), set link attributes\n var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);\n link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}\n link.code="function _out(place){"+lookaheadMatch[4]+"\sn};_out(this);"\n link.setAttribute("href","javascript:;"); link.setAttribute("title",""); link.style.cursor="pointer";\n }\n else { // run inline script code\n var code="function _out(place){"+lookaheadMatch[4]+"\sn};_out(w.output);"\n code=code.replace(/document.write\s(/gi,'place.innerHTML+=(');\n try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }\n if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);\n }\n }\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n} )\n//}}}\n
/%\n\nDerived from http://www.squarefree.com/shell/?ignoreReferrerFrom=shell1.4\n\n%/<html><div class="shell"><div id="output"></div><input type=text\n onkeydown="jsshell.inputKeydown(event)"\n id="input" class="input" wrap="off" autocomplete="off"\n title="TAB=auto-complete property names, Ctrl+Up/Down=history"\n style="width:100%;margin-top:.2em;border:1px solid;color:#000;background:#fff;"><span style="float:right">height: <input type="text" name="height" value="20em" size="2" style="width:3em;padding:0;margin:0;" onchange="document.getElementById('output').style.height=this.value"> <input type="button" onclick="jsshell.go('clear()')"value="clear"></span><!--\n --><div>enter a javascript expression or shell function:\n ans, load(URL), scope(obj), <!--\n --><a accesskey="M" href="javascript:jsshell.go('scope(Math); mathHelp();');">Math</a>, <!--\n --><a accesskey="P" href="javascript:jsshell.go('props(ans)')">props(obj)</a>, <!--\n --><a accesskey="B" href="javascript:jsshell.go('blink(ans)')">blink(node)</a>, <!--\n --><a href="javascript:jsshell.go('wikify(ans)')">wikify(text)</a>, <!--\n --><a href="javascript:jsshell.go('print(ans)')">print(text)</a></div></div></html><script>\n\nvar shellstyles="";\nshellstyles+=".shell #output { height:20em;width:100%;white-space:normal;overflow:auto; }";\nshellstyles+=".shell #output { border:1px solid #999;background:#000 !important; }";\nshellstyles+=".shell #output .input { color:#fff !important; }"; // white\nshellstyles+=".shell #output .error { color:#f00 !important; }"; // red\nshellstyles+=".shell #output .normalOutput { color:#0c0 !important; }"; // green\nshellstyles+=".shell #output .propList { color:#0c0 !important; }"; // green\nshellstyles+=".shell #output .print { color:#ccc !important; }"; // gray\nshellstyles+=".shell #output .tabcomplete { color:#ff0 !important; }"; // yellow\nshellstyles+=".shell #output .message { color:#0ff !important; }"; // cyan\nsetStylesheet(shellstyles,"JavascriptShellStyles");\n\nwindow.jsshell = {}; // Put our functions in the global namespace.\n\nwindow.jsshell.refocus = function()\n{\n jsshell._in.blur(); // Needed for Mozilla to scroll correctly.\n jsshell._in.focus();\n}\n\nwindow.jsshell.initTarget = function()\n{\n window.print = jsshell.shellCommands.print;\n}\n\n// Unless the user is selected something, refocus the textbox.\n// (requested by caillon, brendan, asa)\nwindow.jsshell.keepFocusInTextbox = function(e) \n{\n var g = e.srcElement ? e.srcElement : e.target; // IE vs. standard\n \n while (!g.tagName)\n g = g.parentNode;\n var t = g.tagName.toUpperCase();\n if (t=="A" || t=="INPUT")\n return;\n \n if (window.getSelection) {\n // Mozilla\n if (String(window.getSelection()))\n return;\n }\n else if (document.getSelection) {\n // Opera? Netscape 4?\n if (document.getSelection())\n return;\n }\n else {\n // IE\n if ( document.selection.createRange().text )\n return;\n }\n \n jsshell.refocus();\n}\n\n//function inputKeydown(e) {\nwindow.jsshell.inputKeydown = function(e) {\n // Use onkeydown because IE doesn't support onkeypress for arrow keys\n\n //alert(e.keyCode + " ^ " + e.keycode);\n\n if (e.shiftKey && e.keyCode == 13) { // shift-enter\n // don't do anything; allow the shift-enter to insert a line break as normal\n } else if (e.keyCode == 13) { // enter\n // execute the input on enter\n try { jsshell.go(); } catch(er) { alert(er); };\n setTimeout(function() { jsshell._in.value = ""; }, 0); // can't preventDefault on input, so clear it later\n } else if (e.keyCode == 38) { // up\n // go up in history if at top or ctrl-up\n if (e.ctrlKey || jsshell.caretInFirstLine(jsshell._in))\n jsshell.hist(true);\n } else if (e.keyCode == 40) { // down\n // go down in history if at end or ctrl-down\n if (e.ctrlKey || jsshell.caretInLastLine(jsshell._in))\n jsshell.hist(false);\n } else if (e.keyCode == 9) { // tab\n jsshell.tabcomplete();\n setTimeout(function() { jsshell.refocus(); }, 0); // refocus because tab was hit\n } else { }\n\n setTimeout(jsshell.recalculateInputHeight, 0);\n \n //return true;\n};\n\nwindow.jsshell.caretInFirstLine = function(textbox)\n{\n // IE doesn't support selectionStart/selectionEnd\n if (textbox.selectionStart == undefined)\n return true;\n\n var firstLineBreak = textbox.value.indexOf("\sn");\n\n return ((firstLineBreak == -1) || (textbox.selectionStart <= firstLineBreak));\n}\n\nwindow.jsshell.caretInLastLine = function(textbox)\n{\n // IE doesn't support selectionStart/selectionEnd\n if (textbox.selectionEnd == undefined)\n return true;\n\n var lastLineBreak = textbox.value.lastIndexOf("\sn");\n \n return (textbox.selectionEnd > lastLineBreak);\n}\n\nwindow.jsshell.recalculateInputHeight = function()\n{\n var rows = jsshell._in.value.split(/\sn/).length\n + 1 // prevent scrollbar flickering in Mozilla\n + (window.opera ? 1 : 0); // leave room for scrollbar in Opera\n\n if (jsshell._in.rows != rows) // without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.\n jsshell._in.rows = rows;\n}\n\nwindow.jsshell.println = function(s, type)\n{\n if((s=String(s)))\n {\n var newdiv = document.createElement("div");\n newdiv.appendChild(document.createTextNode(s));\n newdiv.className = type;\n jsshell._out.appendChild(newdiv);\n jsshell._out.scrollTop=jsshell._out.scrollHeight-jsshell._out.clientHeight; // ELS: scroll output into view\n return newdiv;\n }\n}\n\nwindow.jsshell.printWithRunin = function(h, s, type)\n{\n var div = jsshell.println(s, type);\n var head = document.createElement("strong");\n head.appendChild(document.createTextNode(h + ": "));\n div.insertBefore(head, div.firstChild);\n}\n\nwindow.jsshell.shellCommands = \n{\nload : function load(url)\n{\n var s = document.createElement("script");\n s.type = "text/javascript";\n s.src = url;\n document.getElementsByTagName("head")[0].appendChild(s);\n jsshell.println("Loading " + url + "...", "message");\n},\n\nclear : function clear()\n{\n jsshell._out.innerHTML = "";\n},\n\nwikify : function wikify(text)\n{\n window.wikify(text, jsshell._out);\n},\n\nprint : function print(s) { jsshell.println(s, "print"); },\n\n// the normal function, "print", shouldn't return a value\n// (suggested by brendan; later noticed it was a problem when showing others)\npr : function pr(s) \n{ \n jsshell.shellCommands.print(s); // need to specify shellCommands so it doesn't try window.print()!\n return s;\n},\n\nprops : function props(e, onePerLine)\n{\n if (e === null) {\n jsshell.println("props called with null argument", "error");\n return;\n }\n\n if (e === undefined) {\n jsshell.println("props called with undefined argument", "error");\n return;\n }\n\n var ns = ["Methods", "Fields", "Unreachables"];\n var as = [[], [], []]; // array of (empty) arrays of arrays!\n var p, j, i; // loop variables, several used multiple times\n\n var protoLevels = 0;\n\n for (p = e; p; p = p.__proto__)\n {\n for (i=0; i<ns.length; ++i)\n as[i][protoLevels] = [];\n ++protoLevels;\n }\n\n for(var a in e)\n {\n // Shortcoming: doesn't check that VALUES are the same in object and prototype.\n\n var protoLevel = -1;\n try\n {\n for (p = e; p && (a in p); p = p.__proto__)\n ++protoLevel;\n }\n catch(er) { protoLevel = 0; } // "in" operator throws when param to props() is a string\n\n var type = 1;\n try\n {\n if ((typeof e[a]) == "function")\n type = 0;\n }\n catch (er) { type = 2; }\n\n as[type][protoLevel].push(a);\n }\n\n function times(s, n) { return n ? s + times(s, n-1) : ""; }\n\n for (j=0; j<protoLevels; ++j)\n for (i=0;i<ns.length;++i)\n if (as[i][j].length) \n jsshell.printWithRunin(\n ns[i] + times(" of prototype", j), \n (onePerLine ? "\sn\sn" : "") + as[i][j].sort().join(onePerLine ? "\sn" : ", ") + (onePerLine ? "\sn\sn" : ""), \n "propList"\n );\n},\n\nblink : function blink(node)\n{\n if (!node) throw("blink: argument is null or undefined.");\n if (node.nodeType == null) throw("blink: argument must be a node.");\n if (node.nodeType == 3) throw("blink: argument must not be a text node");\n if (node.documentElement) throw("blink: argument must not be the document object");\n\n function setOutline(o) { \n return function() {\n if (node.style.outline != node.style.bogusProperty) {\n // browser supports outline (Firefox 1.1 and newer, CSS3, Opera 8).\n node.style.outline = o;\n }\n else if (node.style.MozOutline != node.style.bogusProperty) {\n // browser supports MozOutline (Firefox 1.0.x and older)\n node.style.MozOutline = o;\n }\n else {\n // browser only supports border (IE). border is a fallback because it moves things around.\n node.style.border = o;\n }\n }\n } \n \n function focusIt(a) {\n return function() {\n a.focus(); \n }\n }\n\n if (node.ownerDocument) {\n var windowToFocusNow = (node.ownerDocument.defaultView || node.ownerDocument.parentWindow); // Moz vs. IE\n if (windowToFocusNow)\n setTimeout(focusIt(windowToFocusNow.top), 0);\n }\n\n for(var i=1;i<7;++i)\n setTimeout(setOutline((i%2)?'3px solid red':'none'), i*100);\n\n setTimeout(focusIt(window), 800);\n setTimeout(focusIt(jsshell._in), 810);\n},\n\nscope : function scope(sc)\n{\n if (!sc) sc = {};\n jsshell._scope = sc;\n jsshell.println("Scope is now " + sc + ". If a variable is not found in this scope, window will also be searched. New variables will still go on window.", "message");\n},\n\nmathHelp : function mathHelp()\n{\n jsshell.printWithRunin("Math constants", "E, LN2, LN10, LOG2E, LOG10E, PI, SQRT1_2, SQRT2", "propList");\n jsshell.printWithRunin("Math methods", "abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random, round, sin, sqrt, tan", "propList");\n},\n\nans : undefined\n};\n\n\nwindow.jsshell.hist = function(up)\n{\n // histList[0] = first command entered, [1] = second, etc.\n // type something, press up --> thing typed is now in "limbo"\n // (last item in histList) and should be reachable by pressing \n // down again.\n\n var L = jsshell.histList.length;\n\n if (L == 1)\n return;\n\n if (up)\n {\n if (jsshell.histPos == L-1)\n {\n // Save this entry in case the user hits the down key.\n jsshell.histList[jsshell.histPos] = jsshell._in.value;\n }\n\n if (jsshell.histPos > 0)\n {\n jsshell.histPos--;\n // Use a timeout to prevent up from moving cursor within new text\n // Set to nothing first for the same reason\n setTimeout(\n function() {\n jsshell._in.value = ''; \n jsshell._in.value = jsshell.histList[jsshell.histPos];\n var caretPos = jsshell._in.value.length;\n if (jsshell._in.setSelectionRange) \n jsshell._in.setSelectionRange(caretPos, caretPos);\n },\n 0\n );\n }\n } \n else // down\n {\n if (jsshell.histPos < L-1)\n {\n jsshell.histPos++;\n jsshell._in.value = jsshell.histList[jsshell.histPos];\n }\n else if (jsshell.histPos == L-1)\n {\n // Already on the current entry: clear but save\n if (jsshell._in.value)\n {\n jsshell.histList[jsshell.histPos] = jsshell._in.value;\n ++jsshell.histPos;\n jsshell._in.value = "";\n }\n }\n }\n}\n\nwindow.jsshell.tabcomplete = function()\n{\n /*\n * Working backwards from s[from], find the spot\n * where this expression starts. It will scan\n * until it hits a mismatched ( or a space,\n * but it skips over quoted strings.\n * If stopAtDot is true, stop at a '.'\n */\n function findbeginning(s, from, stopAtDot)\n {\n /*\n * Complicated function.\n *\n * Return true if s[i] == q BUT ONLY IF\n * s[i-1] is not a backslash.\n */\n function equalButNotEscaped(s,i,q)\n {\n if(s.charAt(i) != q) // not equal go no further\n return false;\n\n if(i==0) // beginning of string\n return true;\n\n if(s.charAt(i-1) == '\s\s') // escaped?\n return false;\n\n return true;\n }\n\n var nparens = 0;\n var i;\n for(i=from; i>=0; i--)\n {\n if(s.charAt(i) == ' ')\n break;\n\n if(stopAtDot && s.charAt(i) == '.')\n break;\n \n if(s.charAt(i) == ')')\n nparens++;\n else if(s.charAt(i) == '(')\n nparens--;\n\n if(nparens < 0)\n break;\n\n // skip quoted strings\n if(s.charAt(i) == '\s'' || s.charAt(i) == '\s"')\n {\n //dump("skipping quoted chars: ");\n var quot = s.charAt(i);\n i--;\n while(i >= 0 && !equalButNotEscaped(s,i,quot)) {\n //dump(s.charAt(i));\n i--;\n }\n //dump("\sn");\n }\n }\n return i;\n }\n\n // XXX should be used more consistently (instead of using selectionStart/selectionEnd throughout code)\n // XXX doesn't work in IE, even though it contains IE-specific code\n function getcaretpos(inp)\n {\n if(inp.selectionEnd != null)\n return inp.selectionEnd;\n \n if(inp.createTextRange)\n {\n var docrange = document.selection.createRange();\n var inprange = inp.createTextRange();\n if (inprange.setEndPoint)\n {\n inprange.setEndPoint('EndToStart', docrange);\n return inprange.text.length;\n }\n }\n\n return inp.value.length; // sucks, punt\n }\n\n function setselectionto(inp,pos)\n {\n if(inp.selectionStart) {\n inp.selectionStart = inp.selectionEnd = pos;\n }\n else if(inp.createTextRange) {\n var docrange = document.selection.createRange();\n var inprange = inp.createTextRange();\n inprange.move('character',pos);\n inprange.select();\n }\n else { // err...\n /*\n inp.select();\n if(document.getSelection())\n document.getSelection() = "";\n */\n }\n }\n // get position of cursor within the input box\n var caret = getcaretpos(jsshell._in);\n\n if(caret) {\n //dump("----\sn");\n var dotpos, spacepos, complete, obj;\n //dump("caret pos: " + caret + "\sn");\n // see if there's a dot before here\n dotpos = findbeginning(jsshell._in.value, caret-1, true);\n //dump("dot pos: " + dotpos + "\sn");\n if(dotpos == -1 || jsshell._in.value.charAt(dotpos) != '.') {\n dotpos = caret;\n//dump("changed dot pos: " + dotpos + "\sn");\n }\n\n // look backwards for a non-variable-name character\n spacepos = findbeginning(jsshell._in.value, dotpos-1, false);\n //dump("space pos: " + spacepos + "\sn");\n // get the object we're trying to complete on\n if(spacepos == dotpos || spacepos+1 == dotpos || dotpos == caret)\n {\n // try completing function args\n if(jsshell._in.value.charAt(dotpos) == '(' ||\n (jsshell._in.value.charAt(spacepos) == '(' && (spacepos+1) == dotpos))\n {\n var fn,fname;\n var from = (jsshell._in.value.charAt(dotpos) == '(') ? dotpos : spacepos;\n spacepos = findbeginning(jsshell._in.value, from-1, false);\n\n fname = jsshell._in.value.substr(spacepos+1,from-(spacepos+1));\n //dump("fname: " + fname + "\sn");\n try {\n with(window)\n with(jsshell._scope)\n with(jsshell.shellCommands)\n fn = eval(fname);\n }\n catch(er) {\n //dump('fn is not a valid object\sn');\n return;\n }\n if(fn == undefined) {\n //dump('fn is undefined');\n return;\n }\n if(fn instanceof Function)\n {\n // Print function definition, including argument names, but not function body\n if(!fn.toString().match(/function .+?\s(\s) +\s{\sn +\s[native code\s]\sn\s}/))\n jsshell.println(fn.toString().match(/function .+?\s(.*?\s)/), "tabcomplete");\n }\n\n return;\n }\n else\n obj = window;\n }\n else\n {\n var objname = jsshell._in.value.substr(spacepos+1,dotpos-(spacepos+1));\n //dump("objname: |" + objname + "|\sn");\n try {\n with(jsshell._scope)\n with(window)\n obj = eval(objname);\n }\n catch(er) {\n jsshell.printError(er); \n return;\n }\n if(obj == undefined) {\n // sometimes this is tabcomplete's fault, so don't print it :(\n // e.g. completing from "print(document.getElements"\n // jsshell.println("Can't complete from null or undefined expression " + objname, "error");\n return;\n }\n }\n //dump("obj: " + obj + "\sn");\n // get the thing we're trying to complete\n if(dotpos == caret)\n {\n if(spacepos+1 == dotpos || spacepos == dotpos)\n {\n // nothing to complete\n //dump("nothing to complete\sn");\n return;\n }\n\n complete = jsshell._in.value.substr(spacepos+1,dotpos-(spacepos+1));\n }\n else {\n complete = jsshell._in.value.substr(dotpos+1,caret-(dotpos+1));\n }\n //dump("complete: " + complete + "\sn");\n // ok, now look at all the props/methods of this obj\n // and find ones starting with 'complete'\n var matches = [];\n var bestmatch = null;\n for(var a in obj)\n {\n //a = a.toString();\n //XXX: making it lowercase could help some cases,\n // but screws up my general logic.\n if(a.substr(0,complete.length) == complete) {\n matches.push(a);\n ////dump("match: " + a + "\sn");\n // if no best match, this is the best match\n if(bestmatch == null)\n {\n bestmatch = a;\n }\n else {\n // the best match is the longest common string\n function min(a,b){ return ((a<b)?a:b); }\n var i;\n for(i=0; i< min(bestmatch.length, a.length); i++)\n {\n if(bestmatch.charAt(i) != a.charAt(i))\n break;\n }\n bestmatch = bestmatch.substr(0,i);\n ////dump("bestmatch len: " + i + "\sn");\n }\n ////dump("bestmatch: " + bestmatch + "\sn");\n }\n }\n bestmatch = (bestmatch || "");\n ////dump("matches: " + matches + "\sn");\n var objAndComplete = (objname || obj) + "." + bestmatch;\n //dump("matches.length: " + matches.length + ", jsshell.tooManyMatches: " + jsshell.tooManyMatches + ", objAndComplete: " + objAndComplete + "\sn");\n if(matches.length > 1 && (jsshell.tooManyMatches == objAndComplete || matches.length <= 10)) {\n\n jsshell.printWithRunin("Matches: ", matches.join(', '), "tabcomplete");\n jsshell.tooManyMatches = null;\n }\n else if(matches.length > 10)\n {\n jsshell.println(matches.length + " matches. Press tab again to see them all", "tabcomplete");\n jsshell.tooManyMatches = objAndComplete;\n }\n else {\n jsshell.tooManyMatches = null;\n }\n if(bestmatch != "")\n {\n var sstart;\n if(dotpos == caret) {\n sstart = spacepos+1;\n }\n else {\n sstart = dotpos+1;\n }\n jsshell._in.value = jsshell._in.value.substr(0, sstart)\n + bestmatch\n + jsshell._in.value.substr(caret);\n setselectionto(jsshell._in,caret + (bestmatch.length - complete.length));\n }\n }\n}\n\nwindow.jsshell.printQuestion = function(q)\n{\n jsshell.println(q, "input");\n}\n\nwindow.jsshell.printAnswer = function(a)\n{\n if (a !== undefined) {\n jsshell.println(a, "normalOutput");\n jsshell.shellCommands.ans = a;\n }\n}\n\nwindow.jsshell.printError = function(er)\n{ \n var lineNumberString;\n\n lastError = er; // for debugging the shell\n if (er.name)\n {\n // lineNumberString should not be "", to avoid a very wacky bug in IE 6.\n lineNumberString = (er.lineNumber != undefined) ? (" on line " + er.lineNumber + ": ") : ": ";\n jsshell.println(er.name + lineNumberString + er.message, "error"); // Because IE doesn't have error.toString.\n }\n else\n jsshell.println(er, "error"); // Because security errors in Moz /only/ have toString.\n}\n\nwindow.jsshell.go = function(s)\n{\n jsshell._in.value = jsshell.question = s ? s : jsshell._in.value;\n\n if (jsshell.question == "")\n return;\n\n jsshell.histList[jsshell.histList.length-1] = jsshell.question;\n jsshell.histList[jsshell.histList.length] = "";\n jsshell.histPos = jsshell.histList.length - 1;\n \n // Unfortunately, this has to happen *before* the JavaScript is run, so that \n // print() output will go in the right place.\n jsshell._in.value='';\n jsshell.recalculateInputHeight();\n jsshell.printQuestion(jsshell.question);\n\n if (window.closed) {\n jsshell.printError("Target window has been closed.");\n return;\n }\n \n try { ("jsshell" in window) }\n catch(er) {\n jsshell.printError("The JavaScript Shell cannot access variables in the target window. The most likely reason is that the target window now has a different page loaded and that page has a different hostname than the original page.");\n return;\n }\n\n if (!("jsshell" in window))\n initTarget(); // silent\n\n // Evaluate Shell.question using _win's eval (this is why eval isn't in the |with|, IIRC).\n// window.location.href = "javascript:try{ jsshell.printAnswer(eval('with(jsshell._scope) with(jsshell.shellCommands) {' + jsshell.question + String.fromCharCode(10) + '}')); } catch(er) { jsshell.printError(er); }; setTimeout(jsshell.refocus, 0); void 0";\n try { \n jsshell.printAnswer(eval(\n 'with(jsshell._scope) with(jsshell.shellCommands) {' \n + jsshell.question + String.fromCharCode(10) + \n '}')); \n } catch(er) { \n jsshell.printError(er); \n }; \n setTimeout(jsshell.refocus, 0);\n}\n\nwindow.jsshell.histList = [""]; \nwindow.jsshell.histPos = 0; \nwindow.jsshell._scope = {}; \nwindow.jsshell.question;\nwindow.jsshell._in;\nwindow.jsshell._out;\nwindow.jsshell.tooManyMatches = null;\nwindow.jsshell.lastError = null;\n\njsshell._in = document.getElementById("input");\njsshell._out = document.getElementById("output");\n\njsshell.initTarget();\n\njsshell.recalculateInputHeight();\njsshell.refocus();\n\n</script>
/***\n|Launch Application Plugin|\n|Authors: Lyall Pearce, modified by Bradley Meck|\n|Bug Finders: HarryC|\n|Source: http://bradleymeck.tiddlyspot.com/#LaunchApplicationPlugin|\n|License: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|Version: 1.1.0|\n|Description: Launch an application from within TiddlyWiki using a button|\n|Usage: {{{<<LaunchApplication "buttonLabel" "tooltip" "application" "argument1" "argument2"...>>}}}|\n\n!Example\n@@PLEASE DO NOT USE THIS IF YOU ARE WORRIED ABOUT SECURITY,\nTIDDLYSPOT, LYALL PEARCE AND MYSELF ARE NOT RESPONSIBLE FOR ANY MIS-USE OF THIS PLUGIN@@\n{{{\n<<LaunchApplication "Open Notepad" "Text Editing"\n"file:///c:/Windows/notepad.exe">>\n}}}\n<<LaunchApplication "Open Notepad" "Text Editing"\n"file:///c:/Windows/notepad.exe">>\n\n{{{\n<<LaunchApplication "C Drive" "Folder" "file:///c:/">>\n}}}\n<<LaunchApplication "C Drive" "Folder" "file:///c:/">>\n\n!To Do\n*Support true XPaths\n**relative paths\n***{{{..}}} : parent-directory\n***{{{/}}} : root-directory\n**wild-cards\n***{{{*}}} : unknown-name\n\n!Revisions\n*11/07/2006 : Problem with application parameters was fixed in IE.\n*11/06/2006 : Problem with application parameters appeared again. Fixed in Firefox for now. Thanks to HarryC for bringing up the bug.\n*11/04/2006 : Problem with application parameters was fixed so that they work now.\n*10/29/2006 : Removed Alert of the address being launched and added support for non-application files in Firefox. Fixed a problem from the current directory being recieved by the W.Shell object by using decodeURI. Added absolute paths if the URL has "file:///" as its beginning. Clicking did not return false and was firing beforeUnLoad(), fixed that.\n*10/28/2006 : Added Support for Firefox in Windows (changes how nsILocalFile is recieved) and changes the functions to use decodeURI for more compatibility.\n\n***/\n//{{{\nversion.extensions.LaunchApplication = {major: 1, minor: 1, revision: 0, date: new Date(2006,11,07)};\nconfig.macros.LaunchApplication = {};\n\nfunction LaunchApplication(appToLaunch,appParams) {\n if(! appToLaunch)\n return;\n if(config.browser.isIE) {\n // want where the tiddly is actually located, excluding tiddly html file\n var tiddlyBaseDir = self.location.pathname.substring(0,self.location.pathname.lastIndexOf("\s\s")+1);\n if(!tiddlyBaseDir || tiddlyBaseDir == "") {\n tiddlyBaseDir = self.location.pathname.substring(0,self.location.pathname.lastIndexOf("/")+1);\n }\n // if Returns with a leading slash, we don't want that.\n if(tiddlyBaseDir.substring(0,1) == "/") {\n tiddlyBaseDir = tiddlyBaseDir.substring(1);\n }\n var theShell = new ActiveXObject("WScript.Shell");\n if(theShell) {\n // the app name may have a directory component, need that too\n // as we want to start with current working dir as the location\n // of the app.\n if(appToLaunch.indexOf("file:///") == 0)\n {\n tiddlyBaseDir = "";\n appToLaunch = appToLaunch.substring(8);\n }\n var appDir = appToLaunch.substring(0, appToLaunch.lastIndexOf("\s\s"));\n if(! appDir || appDir == "") {\n appDir = appToLaunch.substring(0, appToLaunch.lastIndexOf("/"));\n }\n appParams = appParams.length>0?" \s""+appParams.join("\s" \s"")+"\s"":"";\n theShell.CurrentDirectory = decodeURI(tiddlyBaseDir + appDir);\n var commandString = ('"' +decodeURI(tiddlyBaseDir+appToLaunch) + '" ' + appParams);\n pluginInfo.log.push(commandString);\n theShell.run(commandString);\n } else {\n pluginInfo.log.push("WScript.Shell object not created");\n }\n } else {\n // want where the tiddly is actually located, excluding tiddly html file\n var tiddlyBaseDir = self.location.href.substring(0,self.location.href.lastIndexOf("\s\s")+1);\n if(!tiddlyBaseDir || tiddlyBaseDir == "") {\n tiddlyBaseDir = self.location.href.substring(0,self.location.href.lastIndexOf("/")+1);\n }\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\n if(appToLaunch.indexOf("file:///") == 0)\n {\n tiddlyBaseDir = "";\n appToLaunch = appToLaunch.substring(8);\n }\n file.initWithPath(decodeURI(tiddlyBaseDir+appToLaunch).replace(/\s//g,"\s\s"))\n if (file.isFile() && file.isExecutable()) {\n var process = Components.classes['@mozilla.org/process/util;1'].createInstance(Components.interfaces.nsIProcess);\n process.init(file);\n process.run(false, appParams, appParams.length);\n }\n else\n {\n file.launch();\n }\n }\n};\n\nconfig.macros.LaunchApplication.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n // 0=ButtonText, 1=toolTop, 2=AppToLaunch, 3...AppParameters\n if (params[0] && params[1] && params[2]) {\n var theButton = createTiddlyButton(place, params[0], params[1], onClickLaunchApplication);\n theButton.setAttribute("appToLaunch", params[2]);\n var appParams = [];\n for (var i = 3; i <params.length; i++) {\n appParams.push(params[i]);\n }\n theButton.appParameters = appParams;\n return;\n }\n}\n\nfunction onClickLaunchApplication(e) {\n var theAppToLaunch = this.getAttribute("appToLaunch");\n\n var theAppParams = this.appParameters ;\n LaunchApplication(theAppToLaunch,theAppParams);\n return false;\n }\n\n//}}}\n
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n * Etiam rhoncus sodales pede.\n * Nunc consequat lacus sed odio.\n * Integer accumsan nunc elementum mi.\n\n * Nullam luctus molestie mi.\n * Vivamus lacinia enim ut ipsum.\n * In sollicitudin rutrum augue.\n * Nam vestibulum diam cursus neque.\n * Nunc bibendum mauris vel ipsum.\n * Etiam vel sapien in lectus commodo tincidunt.\n\n * Vivamus sit amet ante non leo accumsan congue.\n * Vivamus tempus mattis risus.\n * Praesent rhoncus volutpat sem.\n * Duis fermentum lacinia justo.\n * Nam feugiat convallis libero.\n\n * Phasellus interdum venenatis dui.\n * Cras placerat pede sed dui.\n * Ut sit amet pede ac mauris fermentum tincidunt.\n\n * Fusce ullamcorper gravida metus.\n * Etiam tristique diam non velit.\n * Duis posuere urna non urna.\n * Donec ultricies augue at risus.\n * Maecenas dapibus vestibulum ligula.\n
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n * Etiam @@rhoncus sodales@@ pede.\n * Nunc consequat lacus sed odio.\n * Integer accumsan nunc elementum mi.\n\n * --Nullam luctus molestie mi.--\n * Vivamus lacinia enim ut ipsum.\n * In sollicitudin rutrum augue.\n * Nam vestibulum diam cursus neque.\n * Nunc bibendum mauris vel ipsum.\n * Etiam vel sapien in lectus commodo tincidunt.\n\n * Vivamus sit amet ante non leo accumsan congue.\n * Vivamus tempus mattis risus.\n * Praesent rhoncus volutpat sem.\n * Duis fermentum lacinia justo.\n * Nam feugiat convallis libero.\n\n * ''Phasellus interdum venenatis dui.''\n * {{{Cras placerat pede sed dui.}}}\n * Ut sit amet pede ac mauris fermentum tincidunt.\n\n * Fusce ullamcorper gravida metus.\n * Etiam tristique diam non velit.\n * Duis posuere urna non urna.\n * Donec ultricies augue at risus.\n * Maecenas dapibus vestibulum ligula.\n
/***\n|auth(o(((r)))): Bradley Meck|\n|date: 12/03/2006|\n|use: config.macros.nestedFormatter.getFormatter|\n|params: String name, String openingMatch, String closingMatch, function Handler|\n\n!About\nThis plugin's purpose is to produce a formatter that will allow for it to have nested structures. Included in this macro is an example at the bottom using parenthesis to give a font size increasing effect.\n\n!Example text source\n{{{\n((te(s)t (t(hi)s))!)\n}}}\n!Example result\n((te(s)t (t(hi)s))!)\n\n!Example's Code\n{{{\nconfig.formatters.push(\n config.macros.nestedFormatter.getFormatter("paren","\s\s(","\s\s)",function(w,s){\n var elem = createTiddlyElement(w.output,"span")\n wikify(s[1],elem,null,w.tiddler);\n elem.style.fontSize = "120%";\n}));\n}}}\nthe main difference in how the handler for such a handler function works for a nested formatter is that it has a second arguement {{{strArr}}}. {{{strArr}}} has 3 parts, the original tag {{{opening signifier strArr[0]}}} and the middle test {{{what is between the signifiers strArr[1]}}} and the ending tag {{{ending signifier strArr[2]}}}. w.matchText will return the entire string match from the first openning signifier to the last closing signifier {{{inclusive}}}.\n\n!todo\n*restructure the code so that wikify is not called because it is such a heavy function call.\n*handle improper formatting nicely.\n*allow for capturing/bubbling style handler calls.\n\n***/\n\n//{{{\nconfig.macros.nestedFormatter = {};\nconfig.macros.nestedFormatter.getFormatter = function(fname, openTag, closeTag, formattingHandler){\nvar formatterResult = {};\nformatterResult.name = fname;\nformatterResult.match = openTag;\nformatterResult.openRegex = new RegExp(openTag,"m");\nformatterResult.closeRegex = new RegExp(closeTag,"m");\nformatterResult.handler = function(w){\n var testString = w.source.substring(w.matchStart+w.matchLength);\n var strArr = [w.source.substring(w.matchStart,w.matchStart+w.matchLength)];\n var depth = 1;\nvar off = w.matchLength;\nvar index = true;var endex = true;\n while(depth > 0 && (index || endex) && testString.length > 0){\n index = this.openRegex.exec(testString);\n endex = this.closeRegex.exec(testString);\n //Found New Opening\n if(index && endex && index.index < endex.index)\n {\n depth++;\n off+=index.index+index[0].length;\n testString = testString.substring(index[0].length+index.index);\n }\n else if(!index || endex.index < index.index)\n {\n depth--;\n off+=endex.index+endex[0].length;\n testString = testString.substring(endex[0].length+endex.index);\n }\n }\n if(depth != 0){\n createTiddlyText(w.output,w.matchText);\n }\n else{\n w.matchText = w.source.substring(w.matchStart,w.matchStart+off);\nstrArr.push(w.matchText.substring(strArr[0].length,w.matchText.length-endex[0].length));\nstrArr.push(endex[0]);\n w.matchLength = w.matchText.length;\n w.nextMatch = w.matchStart + w.matchLength;\n formattingHandler(w,strArr);\n }\n};\nreturn formatterResult;\n}\n//}}}
var title = new Date( );\ntitle = title.formatString("[[DD MMM YYYY]]");\nstore.saveTiddler( "DefaultTiddlers", "DefaultTiddlers", title );\n
<cond config.options.chkHttpReadOnly==false>username:\n<<option txtUserName>>\n</cond><<option chkRegExpSearch>> RegExpSearch\n<<option chkCaseSensitiveSearch>> CaseSensitiveSearch\n----\nAdvancedOptions<cond config.options.chkHttpReadOnly==false>\nPluginManager\nImportTiddlers\n</cond>
<!--{{{-->\n<div class='header'>\n<div class='headerForeground'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n</div>\n</div>\n<div id='sidebar'>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>\n<!--}}}-->
/***\n| Name:|QuickOpenTagPlugin|\n| Purpose:|Makes tag links into a Taggly style open tag plus a normal style drop down menu|\n| Creator:|SimonBaird|\n| Source:|http://simonbaird.com/mptw/#QuickOpenTagPlugin|\n| Requires:|TW 2.x|\n| Version|1.1 (7-Feb-06)|\n\n!History\n* Version 1.1 (07/02/2006)\n** Fix Firefox 1.5.0.1 crashes\n** Updated by ~BidiX[at]~BidiX.info\n* Version 1.0 (?/01/2006)\n** First release\n\n***/\n//{{{\n\n//⊻ ⊽ ⋁ ▼ \n\nwindow.createTagButton_orig_mptw = createTagButton;\nwindow.createTagButton = function(place,tag,excludeTiddler) {\n var sp = createTiddlyElement(place,"span",null,"quickopentag");\n createTiddlyLink(sp,tag,true,"button");\n var theTag = createTiddlyButton(sp,config.macros.miniTag.dropdownchar,config.views.wikified.tag.tooltip.format([tag]),onClickTag);\n theTag.setAttribute("tag",tag);\n if(excludeTiddler)\n theTag.setAttribute("tiddler",excludeTiddler);\n return(theTag);\n};\n\nconfig.macros.miniTag = {handler:function(place,macroName,params,wikifier,paramString,tiddler) {\n var tagged = store.getTaggedTiddlers(tiddler.title);\n if (tagged.length > 0) {\n var theTag = createTiddlyButton(place,config.macros.miniTag.dropdownchar,config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);\n theTag.setAttribute("tag",tiddler.title);\n theTag.className = "miniTag";\n }\n}};\n\nconfig.macros.miniTag.dropdownchar = (document.all?"▼":"▾"); // the fat one is the only one that works in IE\n\nconfig.macros.allTags.handler = function(place,macroName,params)\n{\n var tags = store.getTags();\n var theDateList = createTiddlyElement(place,"ul",null,null,null);\n if(tags.length === 0)\n createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);\n for (var t=0; t<tags.length; t++)\n {\n var theListItem =createTiddlyElement(theDateList,"li",null,null,null);\n var theLink = createTiddlyLink(theListItem,tags[t][0],true);\n var theCount = " (" + tags[t][1] + ")";\n theLink.appendChild(document.createTextNode(theCount));\n\n var theDropDownBtn = createTiddlyButton(theListItem," "+config.macros.miniTag.dropdownchar,this.tooltip.format([tags[t][0]]),onClickTag);\n theDropDownBtn.setAttribute("tag",tags[t][0]);\n }\n};\n\n\nsetStylesheet(\n ".quickopentag { margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }\sn"+\n ".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }\sn"+\n ".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}\sn"+\n "a.miniTag {font-size:150%;}\sn"+\n "",\n"QuickOpenTagStyles");\n\n//}}}\n\n/***\n<html>&#x22bb; &#x22bd; &#x22c1; &#x25bc; &#x25be;</html>\n***/\n
/***\n| Name:|RenameTagsPlugin|\n| Purpose:|Allows you to easily rename tags|\n| Creator:|SimonBaird|\n| Source:|http://simonbaird.com/mptw/#RenameTagsPlugin|\n| Version:|1.0.1 (5-Mar-06)|\n\n!Description\nIf you rename a tiddler/tag that is tagging other tiddlers this plugin will ask you if you want to rename the tag in each tiddler where it is used. This is essential if you use tags and ever want to rename them. To use it, open the tag you want to rename as a tiddler (it's the last option in the tag popup menu), edit it, rename it and click done. You will asked if you want to rename the tag. Click OK to rename the tag in the tiddlers that use it. Click Cancel to not rename the tag.\n\n!Example\nTry renaming [[Plugins]] or [[CSS]] on this site.\n\n!History\n* 1.0.1 (5-Mar-06) - Added feature to allow renaming of tags without side-effect of creating a tiddler\n* 1.0.0 (5-Mar-06) - First working version\n\n!Code\n***/\n//{{{\n\nversion.extensions.RenameTagsPlugin = {\n major: 1, minor: 0, revision: 0,\n date: new Date(2006,3,5),\n source: "http://simonbaird.com/mptw/#RenameTagsPlugin"\n};\n\nconfig.macros.RenameTagsPlugin = {};\nconfig.macros.RenameTagsPlugin.prompt = "Rename the tag '%0' to '%1' in %2 tidder%3?";\n\n// these are very useful, perhaps they should be in the core\nif (!store.addTag) {\n store.addTag = function(title,tag) {\n var t=this.getTiddler(title); if (!t || !t.tags) return;\n t.tags.push(tag);\n };\n};\n\nif (!store.removeTag) {\n store.removeTag = function(title,tag) {\n var t=this.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)!=null) t.tags.splice(t.tags.find(tag),1);\n };\n};\n\nstore.saveTiddler_orig_tagrename = store.saveTiddler;\nstore.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {\n if (title != newTitle && this.getTaggedTiddlers(title).length > 0) {\n // then we are renaming a tag\n var tagged = this.getTaggedTiddlers(title);\n if (confirm(config.macros.RenameTagsPlugin.prompt.format([title,newTitle,tagged.length,tagged.length>1?"s":""]))) {\n for (var i=0;i<tagged.length;i++) {\n store.removeTag(tagged[i].title,title);\n store.addTag(tagged[i].title,newTitle);\n // if tiddler is visible refresh it to show updated tag\n story.refreshTiddler(tagged[i].title,false,true);\n }\n }\n if (!this.tiddlerExists(title) && newBody == "") {\n // dont create unwanted tiddler\n return null;\n }\n }\n return this.saveTiddler_orig_tagrename(title,newTitle,newBody,modifier,modified,tags);\n}\n\n//}}}\n\n
/***\n!Revisions Plugin\n!!!About\n|Author : Bradley Meck|\n|Date : Dec 24, 2006|\n\nThis plugin allows people to save multiple revisions of tiddlers and view the changes of tiddlers over time with the ability to restore previous versions of a tiddler.\n***/\n//{{{\nconfig.macros.revisionsPlugin = { };\nconfig.macros.revisionsPlugin.addRevision = function( tiddler, newContent ){\n \n}\n//}}}\n\n
<html><span onmousedown='\nvar selection = new config.macros.W3CSelection();\nvar rang = selection.getRangeAt(0);\nvar clone;\nclone = rang.cloneContents();\nfor(var i = 0; i < clone.childNodes.length; i++){\n if(clone.childNodes[i].nodeType != 1){\ndisplayMessage(clone.childNodes[i].text);\nvar clonedNode = clone.childNodes[i].cloneNode(true);\nclone.replaceChild(document.createElement("span"),clone.childNodes[i]);\nclone.childNodes[i].appendChild(clonedNode);\n}\nclone.childNodes[i].style.color = "green";\n}\nrang.deleteContents();\nrang.insertNode(clone);\n'>\nCOLOR ME SELECTION!\n</span>\n\nJAYAYAYAYAYAYAYAYA</html>
<<search>>\n<script>\nplace.style.textAlign = "left"\nplace.style.padding= "1em"\nvar button = createTiddlyElement(place.firstChild,"img");\nbutton.src = "http://i14.photobucket.com/albums/a324/gen329/Website/system-search.png";\nbutton.style.verticalAlign = "middle"\n</script><<permaview>><script>\nvar i = createTiddlyElement(place.lastChild, "img");\ni.src = "http://i14.photobucket.com/albums/a324/gen329/Website/mail-attachment.png";\ni.style.cursor = "pointer";\ni.style.verticalAlign = "middle"\n</script>\n<cond config.options.chkHttpReadOnly == false><<newTiddler>><script>\nvar i = createTiddlyElement(place.lastChild, "img");\ni.src = "http://i14.photobucket.com/albums/a324/gen329/Website/window-new.png";\ni.style.cursor = "pointer";\ni.style.verticalAlign = "middle"\n</script>\n</cond><<slider chkSliderOptionsPanel OptionsPanel 'options ' 'Change TiddlyWiki advanced options'>><script>\nvar i = createTiddlyElement(place.lastChild.previousSibling, "img");\ni.src = "http://i14.photobucket.com/albums/a324/gen329/Website/applications-system.png";\ni.style.cursor = "pointer";\ni.style.verticalAlign = "middle"\n</script>
<<tabs txtMainTab Menu 'Site Menu' SideBarOptions Timeline Timeline TabTimeline All 'All tiddlers' TabAll System 'Core System Tiddlers' TabMoreShadowed>><script>if(config.options.chkHttpReadOnly == true){\n place.firstChild.firstChild.removeChild(place.firstChild.firstChild.childNodes[3]);\n}</script>
/***\nThis CSS by DaveBirss.\n***/\n/*{{{*/\n\n.tabSelected {\n background: #fff;\n}\n\n.tabUnselected {\n background: #eee;\n}\n\n#sidebar {\n color: #000;\n}\n\n#sidebarOptions {\n background: #fff;\n}\n\n#sidebarOptions .button {\n color: #999;\n}\n\n#sidebarOptions .button:hover {\n color: #000;\n background: #fff;\n border-color:white;\n}\n\n#sidebarOptions .button:active {\n color: #000;\n background: #fff;\n}\n\n#sidebarOptions .sliderPanel {\n background: transparent;\n}\n\n#sidebarOptions .sliderPanel A {\n color: #999;\n}\n\n#sidebarOptions .sliderPanel A:hover {\n color: #000;\n background: #fff;\n}\n\n#sidebarOptions .sliderPanel A:active {\n color: #000;\n background: #fff;\n}\n\n.sidebarSubHeading {\n color: #000;\n}\n\n#sidebarTabs {`\n background: #fff\n}\n\n#sidebarTabs .tabSelected {\n color: #000;\n background: #fff;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: none;\n}\n\n#sidebarTabs .tabUnselected {\n color: #999;\n background: #eee;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: none;\n}\n\n#sidebarTabs .tabContents {\n background: #fff;\n}\n\n\n#sidebarTabs .txtMoreTab .tabSelected {\n background: #fff;\n}\n\n#sidebarTabs .txtMoreTab .tabUnselected {\n background: #eee;\n}\n\n#sidebarTabs .txtMoreTab .tabContents {\n background: #fff;\n}\n\n#sidebarTabs .tabContents .tiddlyLink {\n color: #999;\n}\n\n#sidebarTabs .tabContents .tiddlyLink:hover {\n background: #fff;\n color: #000;\n}\n\n#sidebarTabs .tabContents {\n color: #000;\n}\n\n#sidebarTabs .button {\n color: #666;\n}\n\n#sidebarTabs .tabContents .button:hover {\n color: #000;\n background: #fff;\n}\n\n/*}}}*/
~PeachTW
/*{{{*/\n.tagged .quickopentag{\n border: 0px none;\n}\n.tagging .quickopentag{\n border: 0px none;\n}\n#displayArea{\n padding: 0px;\n top: 0px;\n margin-top: 1em;\n margin-left: 16em;\n margin-right: 2em;\n}\n#mainMenu{\n display: none;\n}\n#messageArea{\n border-color: rgb(100,120,250);\n background-color: white;\n}\n#sidebar{\n background-color: white;\n border: 0.3ex solid black;\nleft: 0px;\nmargin: 1em;\n}\n#sidebarTabs{\nmargin: 0px;\npadding: 0.3ex;\ntext-align: center;\n}\n#sidebarTabs a:hover{\nbackground-color: rgb(100,120,250);\ncolor: white;\n}\n#sidebarTabs .tabContents{\n width: 100%;\n}\n*{\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n}\n.headerForeground{\n position: relative;\n padding-top: 1em;\n}\n.tiddler{\n background-color: white;\n padding: 0px;\n margin-top: 0px;\n border: 0.3ex solid black;\n margin-bottom: 1em;\n}\nbody{\n position: static;\n background-image: url('http://i14.photobucket.com/albums/a324/gen329/Website/Background.png');\n background-repeat: repeat;\n}\nhtml{\n font-size: 12pt;\n}\n.header{\n color: white;\n background-color: rgb(100,120,250);\n border-bottom: 0.3ex solid black;\n}\n.header{\n color: white;\n background-color: rgb(100,120,250);\n border-bottom: 0.3ex solid black;\n}\n.tiddler .viewer{\n padding: 1em;\n}\n.tiddler .viewer pre, .tiddler .viewer code{\n background-color: rgb(227,227,227);\n border: 0.3ex solid black;\n}\n.tabContents{\n padding: 0em;\n}\n.tiddler .title{\n color: white;\n background-color: rgb(100,120,250);\n border-bottom: 0.3ex solid black;\n font-size: 12pt;\n padding: 0.3em;\n}\n.tiddler .toolbar{\n text-align: left;\n}\n.tiddler .toolbar .button{\n visibility: visible;\n border: none;\n}\n.tiddler .toolbar a.button:hover{\n background-color: rgb(100,120,250);\n color: white;\n}\nh1,h2,h3,h4,h5,h6{\n color: white;\n background-color: rgb(130,190,255);\n}\n/*}}}*/
/***\n|W3CRange / W3CSelection for IE|h\n!examples\n[[SelectTest]]\n\n|Constructors|h\n\n|config.macros.W3CSelection|\n|arguments : none|\n\n|config.macros.W3CRange|\n|arguments : oldRange or null|\n\n!Basic Methods\n*http://developer.mozilla.org/en/docs/DOM:range without\n{{{\ncomparePoint\n\ncreateContextualFragment\n\nisPointInRange\n}}}\n!Extra\n|method|selectInput |\n|arguments|TextArea , startOffset , endOffset |\n|usage|grabs the selection from a "TextArea" or "Input" tag and sets the start and end offsets |\n\n!Todo\n*add custom method '''range.applyFunctionToRangeElements(func)''' that will do basically a function call on all the nodes in the range with arguements (node,isleaf,range)\n\n***/\n\n//{{{\nconfig.macros.W3CSelection = function(){\n this.oldSelection = window.getSelection?window.getSelection():document.getSelection?document.getSelection():document.selection;\n return this;\n}\n\nconfig.macros.W3CSelection.prototype = {\n getRangeAt: function(n){\n if(this.oldSelection.getRangeAt){\n if(n >= this.oldSelection.rangeCount) return null;\n var oldRange = this.oldSelection.getRangeAt(n);\n return oldRange?(new config.macros.W3CRange(oldRange)):null;\n }\n else{\n var s = this.oldSelection.createRange();\n return s?(new config.macros.W3CRange(s)):null; \n }\n },\n collapse: function(node,offset){\n if(this.oldSelection.collapse){\n this.oldSelection.collapse();\n }\n else{\n this.oldSelection.clear();\n var rang = new config.macros.W3CRange();\n rang.setStart(node,offset);\n rang.collapse(true);\n this.addRange(rang);\n }\n },\n getRanges: function(){\n var rangs = [];\n if(this.oldSelection.getRanges){\n var stuff = this.oldSelection.getRanges();\n for(var i = 0; i < stuff.length; i++){\n rangs.push(new config.macros.W3CRange(stuff[i]));\n }\n }\n else{\n var stuff= this.oldSelection.createRangeCollection();\n for(var i = 0; i < stuff.count; i++){\n rangs.push(new config.macros.W3CRange(stuff.item(i)))\n }\n }\n return rangs;\n },\n extend: function(node,offset){\n if(this.oldSelection.extend){\n this.oldSelection.extend(node,offset);\n }\n else{\n var rang = new config.macros.W3CRange();\n rang.setStart(node,offset);\n rang.collapse(true);\n ranges = this.getRanges();\n var hasBefore = false, hasAfter = false;\n for(var i = 0; i < ranges.length;i++){\n if(ranges[i].compareBoundaryPoint(ranges[i].START_TO_START,rang.oldRange) == -1){\n hadBefore = true;\n }\n if(ranges[i].compareBoundaryPoint(ranges[i].END_TO_END,rang.oldRange) == 1){\n hasAfter = true;\n }\n }\n if(!hasBefore && hasAfter){\n (new config.macros.W3CRange(this.oldSelection.createRange())).setStart(node,offset);\n }\n else if(hasBefore && !hasAfter){\n (new config.macros.W3CRange(this.oldSelection.createRange())).setEnd(node,offset);\n }\n else if(!hasBefore && !hasAfter){\n this.oldSelection.createRangeCollection().add(rang.oldRange);\n }\n }\n },\n addRange: function(rang){\n if(this.oldSelection.addRange){\n this.oldSelection.addRange(rang.oldRange);\n }\n else{\n this.oldSelection.createRangeCollection().add(rang.oldRange);\n }\n },\n removeRange: function(rang){\n if(this.oldSelection.removeRange){\n this.oldSelection.removeRange(rang.oldRange);\n }\n else{\n this.oldSelection.createRangeCollection().remove(rang.oldRange);\n }\n },\n removeAllRanges: function(){\n if(this.oldSelection.removeAllRanges){\n this.oldSelection.removeAllRanges();\n }\n else{\n this.oldSelection.clear();\n }\n }\n}\n\nconfig.macros.W3CRange = function(oldRangeObj){\n if(oldRangeObj){\n this.oldRange = oldRangeObj\n }\n else if(document.createRange){\n this.oldRange = document.createRange();\n }\n else{\n this.oldRange = document.body.createTextRange();\n this.oldRange.collapse();\n }\n var hasAncestor = false;\n if(this.oldRange.commonAncestorContainer){\n this.commonAncestorContainer = this.oldRange.commonAncestorContainer\n hasAncestor = true;\n }\n else if(this.oldRange.parentElement){\n this.commonAncestorContainer = this.oldRange.parentElement();\n hasAncestor = true;\n }\n if(hasAncestor){\n this.collapsed = this.oldRange.collapsed!=null?this.oldRange.collapsed:(this.oldRange.text.length == 0);\n if(this.oldRange.startContainer){\n this.startContainer = this.oldRange.startContainer\n }\n else{\n var rang = this.oldRange.duplicate();\n rang.setEndPoint("StartToStart",this.oldRange);\n rang.setEndPoint("EndToStart",this.oldRange);\n this.oldRange.startContainer = rang.parentElement();\n }\n if(this.oldRange.startOffset != null){\n this.startOffset = this.oldRange.startOffset;\n }\n else if(this.startContainer){\n var compareRange = this.oldRange.duplicate();\n compareRange.moveToElementText(this.startContainer);\n compareRange.setEndPoint("EndToStart",this.oldRange);\n this.startOffset = compareRange.text.length;\n }\n if(this.oldRange.endContainer){\n this.endContainer = this.oldRange.endContainer\n }\n else{\n var rang = this.oldRange.duplicate();\n rang.setEndPoint("EndToEnd",this.oldRange);\n rang.setEndPoint("StartToEnd",this.oldRange);\n this.oldRange.endContainer = rang.parentElement();\n }\n if(this.oldRange.endOffset != null){\n this.endOffset = this.oldRange.endOffset;\n }\n else if(this.endContainer){\n var compareRange = this.oldRange.duplicate();\n compareRange.moveToElementText(this.endContainer);\n compareRange.setEndPoint("StartToEnd",this.oldRange);\n this.endOffset = compareRange.text.length;\n }\n }\n this.START_TO_END = 1\n this.START_TO_START = 2\n this.END_TO_START = 3\n this.END_TO_END = 4\n\n return this;\n}\n\nconfig.macros.W3CRange.prototype = {\n selectInput : function(node,start,end){\n if(node.setSelectionRange)\n {\n this.oldRange = node.setSelectionRange(start?start:0,end?end:node.value.length);\n }\n else if(node.createTextRange){ \n this.oldRange = node.createTextRange(); \n this.oldRange.moveStart("character",start?start:0); \n var endOffset = end?-(node.value.length-end)+1:0;\n this.oldRange.moveEnd("character",endOffset);\n this.oldRange.select();\n }\n else{\n this.selectNode(node);\n }\n config.macros.W3CRange.call(this,this.oldRange)\n },\n setStart : function(startNode,startOffset){\n if(this.oldRange.setStart){\n this.oldRange.setStart(startNode,startOffset);\n }\n else{\n var startRange = this.oldRange.duplicate();\n startRange.moveToElementText(startNode);\n startRange.moveStart("character",startOffset);\n this.oldRange.setEndPoint("StartToStart",startRange);\n }\n config.macros.W3CRange.call(this,this.oldRange)\n },\n setEnd : function(endNode,endOffset){\n if(this.oldRange.setEnd){\n this.oldRange.setEnd(endNode,endOffset);\n }\n else{\n var endRange = this.oldRange.duplicate();\n endRange.moveToElementText(endNode);\n endRange.moveEnd("character",endOffset);\n this.oldRange.setEndPoint("EndToEnd",endRange);\n }\n config.macros.W3CRange.call(this,this.oldRange)\n },\n setStartBefore: function(node){\n if(this.oldRange.setStartBefore){\n this.oldRange.setStartBefore(node);\n }\n else{\n var startRange = this.oldRange.duplicate();\n startRange.moveToElementText(node);\n this.oldRange.setEndPoint("StartToStart",startRange);\n }\n config.macros.W3CRange.call(this,this.oldRange)\n },\n setStartAfter: function(node){\n if(this.oldRange.setStartAfter){\n this.oldRange.setStartAfter(node);\n }\n else{\n var startRange = this.oldRange.duplicate();\n startRange.moveToElementText(node);\n this.oldRange.setEndPoint("StartToEnd",startRange);\n }\n config.macros.W3CRange.call(this,this.oldRange)\n },\n setEndBefore: function(node){\n if(this.oldRange.setEndBefore){\n this.oldRange.setEndBefore(node);\n }\n else{\n var endRange = this.oldRange.duplicate();\n endRange.moveToElementText(node);\n this.oldRange.setEndPoint("EndToStart",endRange);\n }\n config.macros.W3CRange.call(this,this.oldRange)\n },\n setEndAfter: function(node){\n if(this.oldRange.setEndAfter){\n this.oldRange.setEndAfter(node);\n }\n else{\n var endRange = this.oldRange.duplicate();\n endRange.moveToElementText(node);\n this.oldRange.setEndPoint("EndToEnd",endRange);\n }\n config.macros.W3CRange.call(this,this.oldRange)\n },\n selectNode: function(node){\n this.oldRange.selectNode?this.oldRange.selectNode(node):this.oldRange.moveToElementText(node);\n config.macros.W3CRange.call(this,this.oldRange)\n },\n selectNodeContents: function(node){\n this.oldRange.selectNodeContents?this.oldRange.selectNodeContents(node):this.oldRange.moveToElementText(node);\n config.macros.W3CRange.call(this,this.oldRange)\n },\n collapse: function(toStart){this.oldRange.collapse(toStart);/*IE AND W3C! AMAZING!*/},\n cloneContents: function(){\n if(this.oldRange.cloneContents){\n return this.oldRange.cloneContents();\n }\n else{\n var range = this.oldRange.duplicate();\n var deleter = this.oldRange.duplicate();\n var result = this.commonAncestorContainer.cloneNode(true);\n document.body.appendChild(result);\n range.moveToElementText(this.commonAncestorContainer);\n range.setEndPoint("EndToStart",this.oldRange);\n var n = range.text.length;\n var startClip = n>0?true:false;\n deleter.moveToElementText(result);\n deleter.collapse(true);\n deleter.moveEnd("character",n);\n deleter.text = ""; // Delete beginning\n range.moveToElementText(this.commonAncestorContainer);\n range.setEndPoint("StartToEnd",this.oldRange);\n var n = range.text.length;\n var endClip = n>0?true:false;\n deleter.moveToElementText(result);\n deleter.collapse(false);\n deleter.moveStart("character",-n);\n deleter.text = ""; // Delete end\n document.body.removeChild(result);\n var docFrag = document.createDocumentFragment();\n for(var i = 0; i < result.childNodes.length; i++){\n docFrag.appendChild(result.childNodes[i]);\n }\n return docFrag;\n }\n },\n deleteContents: function(){\n this.oldRange.deleteContents?this.oldRange.deleteContents():(this.oldRange.text = "");\n config.macros.W3CRange.call(this,this.oldRange)\n },\n extractContents: function(){\n if(this.oldRange.extractContents){\n return this.oldRange.extractContents();\n }\n else{\n var e = this.cloneContents();\n this.deleteContents();\n return e;\n }\n },\n/*insertNode: function(node){\n if(this.oldRange.insertNode){\n return this.oldRange.insertNode(node);\n }\n else{\n var range = this.oldRange.duplicate();\n var parent = this.commonAncestorContainer;\n var i = 0;\n range.moveToElementText(parent);\n range.setEndPoint("EndToStart",this.oldRange);\n var targetOffset = range.text.length;\n var offset = 0;\n for(; i < parent.childNodes.length; i++){\n if(parent.childNodes[i].nodeType == 1){//DOM Element\n offset += parent.childNodes[i].innerText.length;\n }\n else{//TEXT NODE\n offset += parent.childNodes[i].length;\n }\n if(offset > targetOffset){\n if(parent.childNodes[i].nodeType == 1){//DOM Element\n offset -= parent.childNodes[i].innerText.length;\n parent = parent.childNodes[i];\n }\n else{//TEXT NODE\n offset -= parent.childNodes[i].length;\n parent.splitText(targetOffset - offset);\n parent.parentNode.insertBefore(node,parent.nextSibling);\n return;\n }\n }\n else if(offset == targetOffset){\n if(parent.childNodes && parent.childNodes[i].nextSibling){\n parent.insertBefore(node,parent.childNodes[i].nextSibling);\n return;\n }\n else{\n break;\n }\n }\n }\n if(i == 0){\n if(parent.childNodes.length > 0){\n parent.insertBefore(node,parent.firstChild);\n }\n else{\n parent.appendChild(node);\n }\n }\n else if(i == parent.childNodes.length){\n parent.appendChild(node);\n }\n }\n}*/\n insertNode: function(node){\n if(this.oldRange.insertNode){\n return this.oldRange.insertNode(node);\n }\n else{\n var range = this.oldRange.duplicate();\n range.collapse();\n var parent = range.parent();\n range.moveToElementText(parent);\n range.moveEndPoint("EndToStart",this.oldRange);\n var offset = range.text.length\n var position = 0;\n var i = 0;\n for(; position < offset; i++){\n if(parent.childNodes[i].innerText){\n position += parent.childNodes[i].innerText.length\n }\n else if(parent.childNodes[i].text){\n position += parent.childNodes[i].text.length\n }\n }\n var elem = parent.childNodes[i]?parent.childNodes[i]:parent;\n range.moveToElementText(elem);\n var dir = range.compareEndPoints("StartToStart",this.oldRange);\n if( dir < 0){\n while( dir < 0 )\n {\n elem = elem.previousSibling;\n range.moveToElementText(elem);\n dir = range.compareEndPoints("StartToStart",this.oldRange);\n }\n }\n else if( dir > 0){\n while( dir > 0 )\n {\n elem = elem.nextSibling;\n range.moveToElementText(elem);\n dir = range.compareEndPoints("StartToStart",this.oldRange);\n }\n }\n elem.parentNode.insertBefore( node, elem );\n }\n },\n surroundContents: function(nodeToInsertInto){\n if(this.oldRange.surroundContents){\n this.oldRange.surroundContents(nodeToInsertInto);\n }\n else{\n nodeToInsertInto.appendChild(this.extractContents());\n this.insertNode(nodeToInsertInto);\n }\n },\n detach: function(){\n if(this.oldRange.detach){\n this.oldRange.detach();\n }\n else{\n this.oldRange = null;\n }\n },\n toString: function(){\n if(this.oldRange.text==null){\n return this.oldRange.toString();\n }\n else{\n if(this.oldRange.text){\n return this.oldRange.text;\n }\n else{\n var par = this.oldRange.parentElement();\n if(par){\n if(par.tagName == "INPUT" || par.tagName == "TEXTAREA"){\n return par.value;\n }\n else{\n return par.innerHTML\n }\n }\n else{\n return "";\n }\n }\n }\n },\n cloneRange: function(){\n return (new config.macros.W3CRange(\n this.oldRange.cloneRange?this.oldRange.cloneRange():this.oldRange.duplicate()\n ));\n },\n compareBoundaryPoints: function(how,otherRange){\n if(how == this.START_TO_START){\n return (this.oldRange.compareBoundaryPoints?\n this.oldRange.compareBoundaryPoints(this.oldRange.START_TO_START,otherRange.oldRange):\n this.oldRange.compareEndPoints("StartToStart",otherRange.oldRange))\n }\n else if(how == this.START_TO_END){\n return (this.oldRange.compareBoundaryPoints?\n this.oldRange.compareBoundaryPoints(this.oldRange.START_TO_END,otherRange.oldRange):\n this.oldRange.compareEndPoints("StartToEnd",otherRange.oldRange))\n }\n else if(how == this.END_TO_START){\n return (this.oldRange.compareBoundaryPoints?\n this.oldRange.compareBoundaryPoints(this.oldRange.END_TO_START,otherRange.oldRange):\n this.oldRange.compareEndPoints("EndToEnd",otherRange.oldRange))\n }\n else if(how == this.END_TO_END){\n return (this.oldRange.compareBoundaryPoints?\n this.oldRange.compareBoundaryPoints(this.oldRange.END_TO_END,otherRange.oldRange):\n this.oldRange.compareEndPoints("EndToEnd",otherRange.oldRange))\n }\n }\n}\n//}}}
/***\nTo use, add {{{[[TagglyTaggingStyles]]}}} to your StyleSheet tiddler, or you can just paste the CSS in directly. See also ViewTemplate, EditTemplate and TagglyTagging.\n***/\n/*{{{*/\n.tagglyTagged li.listTitle { display:none;}\n.tagglyTagged li { display: inline; font-size:90%; }\n.tagglyTagged ul { margin:0px; padding:0px; }\n.tagglyTagging { padding-top:0.5em; }\n.tagglyTagging li.listTitle { display:none;}\n.tagglyTagging ul { margin-top:0px; padding-top:0.5em; padding-left:2em; margin-bottom:0px; padding-bottom:0px; }\n\n/* .tagglyTagging .tghide { display:inline; } */\n\n.tagglyTagging { vertical-align: top; margin:0px; padding:0px; }\n.tagglyTagging table { margin:0px; padding:0px; }\n\n\n.tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }\n.tagglyTagging .button, .tagglyTagging .hidebutton { color:#aaa; font-size:90%; border:0px; padding-left:0.3em;padding-right:0.3em;}\n.tagglyTagging .button:hover, .hidebutton:hover { background:#eee; color:#888; }\n.selected .tagglyTagging .button { display:inline; }\n\n.tagglyTagging .hidebutton { color:white; } /* has to be there so it takes up space */\n.selected .tagglyTagging .hidebutton { color:#aaa }\n\n.tagglyLabel { color:#aaa; font-size:90%; }\n\n.tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }\n.tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}\n.tagglyTagging ul ul li {margin-left:0.5em; }\n\n.editLabel { font-size:90%; padding-top:0.5em; }\n/*}}}*/\n
<script>\nvar error = 5;\nvar reg = new RegExp( "\s\sn|(?:.{0,"+error+"})", "g" );\nvar lorem1 = store.getTiddlerText( "Lorem Ipsum 1" ).match( reg );\nvar lorem2 = store.getTiddlerText( "Lorem Ipsum 2" ).match( reg );\nvar e = diff ( lorem1, lorem2 );\ndisplayMessage( e.toSource( ) );\nvar elem = createTiddlyElement( place, "div" );\nfor( var i = 0; i < e.length; i++ ) {\n var text = createTiddlyElement( elem, "span" );\n switch( e [ i ].change ) {\n case "ADDED":\n wikify( lorem2.slice( e [ i ].index, e [ i ].index + e[ i ].length ).join( "" ), text, null, tiddler );\n text.style.backgroundColor = "rgb( 80, 220, 80)";\n text.style.color = "white";\n break;\n case "DELETED":\n wikify( lorem1.slice( e [ i ].index, e [ i ].index + e[ i ].length ).join( "" ), text, null, tiddler );\n text.style.backgroundColor = "rgb( 220, 80, 80 )";\n text.style.color = "white";\n break;\n default:\n wikify( lorem1.slice( e [ i ].index, e [ i ].index + e[ i ].length ).join( "" ), text, null, tiddler );\n text.style.backgroundColor = "white";\n text.style.color = "black";\n break;\n }\n}\n</script>
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 21/12/2006 12:48:4 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#GettingStarted]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 21/12/2006 12:48:19 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#GettingStarted]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 22/12/2006 1:29:29 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 22/12/2006 3:21:37 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BNewer%20Diff%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 2:25:41 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 2:25:58 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 2:36:12 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 2:47:42 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 2:50:15 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 2:55:26 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 3:1:33 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 3:24:38 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 3:25:29 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 3:30:50 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 3:34:34 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/12/2006 3:34:47 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 3:36:47 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 3:40:28 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 3:48:51 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/12/2006 22:26:54 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 0:44:51 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 0:48:4 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D%20GettingStarted]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 0:50:57 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D%20GettingStarted]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 0:55:59 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D%20GettingStarted]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 0:57:48 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D%20GettingStarted]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:0:1 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:5:26 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:6:16 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:7:13 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:8:45 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:9:42 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:14:35 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:15:19 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D%20%5B%5BTiddler%20Diff%20Attempts%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:29:22 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BDiff%20Function%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:31:20 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:33:57 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:34:46 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:35:15 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:36:36 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:41:41 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 1:41:53 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 1:42:1 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 1:56:52 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#coditionalDisplayFormatter]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 4:2:23 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 4:5:56 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 4:10:26 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 4:11:9 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 4:11:13 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 4:17:16 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 10:47:48 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 10:51:42 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 10:54:0 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 11:2:43 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 11:3:5 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 11:3:16 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 11:3:23 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 11:3:27 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 11:4:35 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 13:59:57 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#HelloWorld]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 24/12/2006 14:9:44 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#HelloWorld]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 24/12/2006 23:53:26 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 1:9:1 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 26/12/2006 1:16:16 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 2:1:23 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:17:39 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:29:20 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:31:47 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:32:58 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:34:19 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:35:48 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:41:47 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:44:21 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:45:22 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 12:47:36 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#%5B%5BJavascript%20Shell%5D%5D]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:22:20 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 26/12/2006 13:33:6 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:38:16 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:38:47 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:39:42 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:40:26 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#search:cond]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:42:47 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#search:cond]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:43:46 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/#search:cond]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:45:31 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:47:7 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:47:41 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/12/2006 13:48:50 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 30/12/2006 2:0:36 | Bradley Meck | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 9/1/2007 9:53:38 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 13/1/2007 14:23:41 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 13/1/2007 14:25:36 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/1/2007 10:48:35 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#start:safemode]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/1/2007 10:49:8 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#start:safemode]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/1/2007 10:49:16 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#start:safemode]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/1/2007 10:49:37 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#start:safemode]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/1/2007 10:49:50 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#start:safemode]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/1/2007 10:50:23 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#start:safemode]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/1/2007 10:50:32 | YourName | [[/|http://bradleymeck.tiddlyspot.com/#start:safemode]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |\n| 26/1/2007 11:38:10 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 26/1/2007 11:40:11 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 26/1/2007 11:43:28 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 26/1/2007 11:48:1 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 26/1/2007 11:56:1 | YourName | [[/|http://bradleymeck.tiddlyspot.com/]] | [[store.php|http://bradleymeck.tiddlyspot.com/store.php]] | . | index.html | . |
/***\n<<tiddler UploadPluginDoc>>\n!Code\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 3, minor: 3, revision: 1, \n date: new Date(2006,3,30),\n type: 'macro',\n source: 'http://tiddlywiki.bidix.info/#UploadPlugin',\n docs: 'http://tiddlywiki.bidix.info/#UploadPluginDoc'\n};\n//}}}\n\n////+++!![config.lib.file]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.file) config.lib.file= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.file.dirname = function (filePath) {\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};\nconfig.lib.file.basename = function (filePath) {\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};\nwindow.basename = function() {return "@@deprecated@@";};\n//}}}\n////===\n\n////+++!![config.lib.log]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.log) config.lib.log= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.Log = function(tiddlerTitle, logHeader) {\n if (version.major < 2)\n this.tiddler = store.tiddlers[tiddlerTitle];\n else\n this.tiddler = store.getTiddler(tiddlerTitle);\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = tiddlerTitle;\n this.tiddler.text = "| !date | !user | !location |" + logHeader;\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[tiddlerTitle] = this.tiddler;\n else\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nconfig.lib.Log.prototype.newLine = function (line) {\n var now = new Date();\n var newText = "| ";\n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += config.options.txtUserName + " | ";\n var location = document.location.toString();\n var filename = config.lib.file.basename(location);\n if (!filename) filename = '/';\n newText += "[["+filename+"|"+location + "]] |";\n this.tiddler.text = this.tiddler.text + "\sn" + newText;\n this.addToLine(line);\n};\n\nconfig.lib.Log.prototype.addToLine = function (text) {\n this.tiddler.text = this.tiddler.text + text;\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[this.tiddler.tittle] = this.tiddler;\n else {\n store.addTiddler(this.tiddler);\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n }\n if (version.major < 2)\n store.notifyAll(); \n};\n//}}}\n////===\n\n////+++!![config.lib.options]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.options) config.lib.options = {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\n\nconfig.lib.options.init = function (name, defaultValue) {\n if (!config.options[name]) {\n config.options[name] = defaultValue;\n saveOptionCookie(name);\n }\n};\n//}}}\n////===\n\n////+++!![PasswordTweak]\n\n//{{{\nversion.extensions.PasswordTweak = {\n major: 1, minor: 0, revision: 2, date: new Date(2006,3,11),\n type: 'tweak',\n source: 'http://tiddlywiki.bidix.info/#PasswordTweak'\n};\n//}}}\n/***\n!!config.macros.option\n***/\n//{{{\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n\nconfig.macros.option.onChangeOption = function(e)\n{\n var opt = this.getAttribute("option");\n var elementType,valueField;\n if(opt) {\n switch(opt.substr(0,3)) {\n case "txt":\n elementType = "input";\n valueField = "value";\n break;\n case "pas":\n elementType = "input";\n valueField = "value";\n break;\n case "chk":\n elementType = "input";\n valueField = "checked";\n break;\n }\n config.options[opt] = this[valueField];\n saveOptionCookie(opt);\n var nodes = document.getElementsByTagName(elementType);\n for(var t=0; t<nodes.length; t++) {\n var optNode = nodes[t].getAttribute("option");\n if (opt == optNode) \n nodes[t][valueField] = this[valueField];\n }\n }\n return(true);\n};\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n var size = 15;\n if (params[1])\n size = params[1];\n if(config.options[opt] === undefined) {\n return;}\n var c;\n switch(opt.substr(0,3)) {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute ("option",opt);\n c.size = size;\n c.value = config.options[opt];\n place.appendChild(c);\n break;\n case "pas":\n // input password\n c = document.createElement ("input");\n c.setAttribute("type",config.macros.option.passwordType);\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.size = size;\n c.value = config.options[opt];\n place.appendChild(c);\n // checkbox link with this password "save this password on this computer"\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option","chk"+opt);\n place.appendChild(c);\n c.checked = config.options["chk"+opt];\n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n place.appendChild(c);\n c.checked = config.options[opt];\n break;\n }\n};\n//}}}\n/***\n!! Option cookie stuff\n***/\n//{{{\nwindow.loadOptionsCookie_orig_PasswordTweak = window.loadOptionsCookie;\nwindow.loadOptionsCookie = function()\n{\n var cookies = document.cookie.split(";");\n for(var c=0; c<cookies.length; c++) {\n var p = cookies[c].indexOf("=");\n if(p != -1) {\n var name = cookies[c].substr(0,p).trim();\n var value = cookies[c].substr(p+1).trim();\n switch(name.substr(0,3)) {\n case "txt":\n config.options[name] = unescape(value);\n break;\n case "pas":\n config.options[name] = unescape(value);\n break;\n case "chk":\n config.options[name] = value == "true";\n break;\n }\n }\n }\n};\n\nwindow.saveOptionCookie_orig_PasswordTweak = window.saveOptionCookie;\nwindow.saveOptionCookie = function(name)\n{\n var c = name + "=";\n switch(name.substr(0,3)) {\n case "txt":\n c += escape(config.options[name].toString());\n break;\n case "chk":\n c += config.options[name] ? "true" : "false";\n // is there an option link with this chk ?\n if (config.options[name.substr(3)]) {\n saveOptionCookie(name.substr(3));\n }\n break;\n case "pas":\n if (config.options["chk"+name]) {\n c += escape(config.options[name].toString());\n } else {\n c += "";\n }\n break;\n }\n c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";\n document.cookie = c;\n};\n//}}}\n/***\n!! Initializations\n***/\n//{{{\n// define config.options.pasPassword\nif (!config.options.pasPassword) {\n config.options.pasPassword = 'defaultPassword';\n window.saveOptionCookie('pasPassword');\n}\n// since loadCookies is first called befor password definition\n// we need to reload cookies\nwindow.loadOptionsCookie();\n//}}}\n////===\n\n////+++!![config.macros.upload]\n\n//{{{\nconfig.macros.upload = {\n accessKey: "U",\n formName: "UploadPlugin",\n contentType: "text/html;charset=UTF-8",\n defaultStoreScript: "store.php"\n};\n\n// only this two configs need to be translated\nconfig.macros.upload.messages = {\n aboutToUpload: "About to upload TiddlyWiki to %0",\n errorDownloading: "Error downloading",\n errorUploadingContent: "Error uploading content",\n fileNotFound: "file to upload not found",\n fileNotUploaded: "File %0 NOT uploaded",\n mainFileUploaded: "Main TiddlyWiki file uploaded to %0",\n urlParamMissing: "url param missing",\n rssFileNotUploaded: "RssFile %0 NOT uploaded",\n rssFileUploaded: "Rss File uploaded to %0"\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.handler = function(place,macroName,params){\n // parameters initialization\n var storeUrl = params[0];\n var toFilename = params[1];\n var backupDir = params[2];\n var uploadDir = params[3];\n var username = params[4];\n var password; // for security reason no password as macro parameter\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 (storeUrl) {\n prompt = this.label.promptParamMacro.toString().format([this.dirname(storeUrl)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {\n config.macros.upload.upload(storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false;}, \n null, null, this.accessKey);\n};\nconfig.macros.upload.UploadLog = function() {\n return new config.lib.Log('UploadLog', " !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |" );\n};\nconfig.macros.upload.UploadLog.prototype = config.lib.Log.prototype;\nconfig.macros.upload.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n var line = " [[" + config.lib.file.basename(storeUrl) + "|" + storeUrl + "]] | ";\n line += uploadDir + " | " + toFilename + " | " + backupDir + " |";\n this.newLine(line);\n};\nconfig.macros.upload.UploadLog.prototype.endUpload = function() {\n this.addToLine(" Ok |");\n};\nconfig.macros.upload.basename = config.lib.file.basename;\nconfig.macros.upload.dirname = config.lib.file.dirname;\nconfig.macros.upload.upload = function(storeUrl, toFilename, uploadDir, backupDir, username, password)\n{\n // parameters initialization\n storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);\n toFilename = (toFilename ? toFilename : config.options.txtUploadFilename);\n if (toFilename === '') {\n toFilename = config.lib.file.basename(document.location.toString());\n }\n backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);\n uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);\n username = (username ? username : config.options.txtUploadUserName);\n password = config.options.pasUploadPassword; // for security reason no password as macro parameter\n\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n if (!storeUrl) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n \n var log = new this.UploadLog();\n log.startUpload(storeUrl, toFilename, uploadDir, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n displayMessage(config.macros.upload.messages.aboutToUpload.format([this.dirname(storeUrl)]), this.dirname(storeUrl));\n this.uploadChanges(storeUrl, toFilename, uploadDir, backupDir, username, password);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toFilename.substr(0,toFilename.lastIndexOf(".")) + ".xml";\n this.uploadContent(rssContent, storeUrl, rssPath, uploadDir, '', username, password, \n function (responseText) {\n if (responseText.substring(0,1) != '0') {\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n if (uploadDir) {\n rssPath = uploadDir + "/" + config.macros.upload.basename(rssPath);\n } else {\n rssPath = config.macros.upload.basename(rssPath);\n }\n displayMessage(config.macros.upload.messages.rssFileUploaded.format(\n [config.macros.upload.dirname(storeUrl)+"/"+rssPath]), config.macros.upload.dirname(storeUrl)+"/"+rssPath);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n });\n }\n return;\n};\n\nconfig.macros.upload.uploadChanges = function(storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original = this.download(storeUrl, toFilename, uploadDir, backupDir, username, password);\n return;\n }\n else {\n // standard way : Local file\n \n original = loadFile(getLocalPath(document.location.toString()));\n if(window.Components) {\n // it's a mozilla browser\n try {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n }\n //DEBUG alert(original);\n this.uploadChangesFrom(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password);\n};\n\nconfig.macros.upload.uploadChangesFrom = function(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it\n var endSaveArea = '</d' + 'iv>';\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([document.location.toString()]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle;\n if(version.major < 2){\n newSiteTitle = (getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode();\n } else {\n newSiteTitle = (wikifyPlain ("SiteTitle") + " - " + wikifyPlain ("SiteSubtitle")).htmlEncode();\n }\n revised = revised.replace(new RegExp("<title>[^<]*</title>", "im"),"<title>"+ newSiteTitle +"</title>");\n var response = this.uploadContent(revised, storeUrl, toFilename, uploadDir, backupDir, \n username, password, function (responseText) {\n if (responseText.substring(0,1) != '0') {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath(document.location.toString())]));\n }\n else {\n if (uploadDir !== '') {\n toFilename = uploadDir + "/" + config.macros.upload.basename(toFilename);\n } else {\n toFilename = config.macros.upload.basename(toFilename);\n }\n displayMessage(config.macros.upload.messages.mainFileUploaded.format(\n [config.macros.upload.dirname(storeUrl)+"/"+toFilename]), config.macros.upload.dirname(storeUrl)+"/"+toFilename);\n var log = new config.macros.upload.UploadLog();\n log.endUpload();\n store.setDirty(false);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n};\n\nconfig.macros.upload.uploadContent = function(content, storeUrl, toFilename, uploadDir, backupDir, \n username, password, callbackFn) {\n var boundary = "---------------------------"+"AaB03x"; \n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n if (window.netscape){\n try {\n if (document.location.toString().substr(0,4) != "http") {\n netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');}\n }\n catch (e) { }\n } \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "\sr\sn";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data;name=\s"";\n sheader += config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir\n +";user=" + username \n +";password=" + password\n +";uploaddir=" + uploadDir\n + ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data;name=\s"userfile\s";filename=\s""+toFilename+"\s"\sr\sn";\n sheader += "Content-Type: " + config.macros.upload.contentType + "\sr\sn";\n sheader += "Content-Length: " + content.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n var data;\n data = sheader + content + strailer;\n //request.open("POST", storeUrl, true, username, password);\n request.open("POST", storeUrl, true);\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if (request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent);\n }\n };\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n};\n\n\nconfig.macros.upload.download = function(uploadUrl, uploadToFilename, uploadDir, uploadBackupDir, \n username, password) {\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n if (uploadUrl.substr(0,4) == "http") {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n else {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n } catch (e) { }\n //request.open("GET", document.location.toString(), true, username, password);\n request.open("GET", document.location.toString(), true);\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n config.macros.upload.uploadChangesFrom(request.responseText, uploadUrl, \n uploadToFilename, uploadDir, uploadBackupDir, username, password);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format(\n [document.location.toString()]));\n }\n };\n request.send(null);\n};\n\n//}}}\n////===\n\n////+++!![Initializations]\n\n//{{{\nconfig.lib.options.init('txtUploadStoreUrl','store.php');\nconfig.lib.options.init('txtUploadFilename','');\nconfig.lib.options.init('txtUploadDir','');\nconfig.lib.options.init('txtUploadBackupDir','');\nconfig.lib.options.init('txtUploadUserName',config.options.txtUserName);\nconfig.lib.options.init('pasUploadPassword','');\nconfig.shadowTiddlers.UploadPluginDoc = "[[Full Documentation|http://tiddlywiki.bidix.info/l#UploadPluginDoc ]]\sn"; \n\n\n//}}}\n////===\n\n////+++!![Core Hijacking]\n\n//{{{\nconfig.macros.saveChanges.label_orig_UploadPlugin = config.macros.saveChanges.label;\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n//}}}\n////===
<!--{{{-->\n<div class='title' macro='view title'><img style="vertical-align: middle; cursor: pointer" src="http://i14.photobucket.com/albums/a324/gen329/Website/emblem-unreadable.png" onclick="\n config.commands.closeTiddler.handler(event,this,story.findContainingTiddler(this).id.substr(7))"\n>\n<img style="vertical-align: middle; cursor: pointer" src="http://i14.photobucket.com/albums/a324/gen329/Website/accessories-text-editor.png" onclick="\n config.commands.editTiddler.handler(event,this,story.findContainingTiddler(this).id.substr(7))"\n>\n<img style="vertical-align: middle; cursor: pointer" src="http://i14.photobucket.com/albums/a324/gen329/Website/emblem-symbolic-link.png" onclick="\n config.commands.jump.handler(event,this,story.findContainingTiddler(this).id.substr(7))"\n>\n<img style="vertical-align: middle; cursor: pointer" src="http://i14.photobucket.com/albums/a324/gen329/Website/mail-attachment.png"" onclick="\n config.commands.permalink.handler(event,this,story.findContainingTiddler(this).id.substr(7))"\n>\n</div>\n<div class='toolbar' style='display: none 'macro='toolbar +closeTiddler closeOthers editTiddler jump'></div>\n<div class='viewer' macro='view text wikified'></div>\n<!--}}}-->
/***\n!Conditional Display Formatter\n!!About\n|Author : Bradley Meck|\n|Date : Dec 24, 2006|\n!!Usage\n{{{\n<cond expression>\n content...\n</cond>\n}}}\n!!Code\n***/\n//{{{\nconfig.macros.conditionalDisplay = { };\nconfig.macros.conditionalDisplay.lookaheadRegExp = /\s<cond[\ss]*([^>]*)\s>/m\nconfig.formatters.push(\n config.macros.nestedFormatter.getFormatter("ConditionalDisplay","<cond\s\ss*[^>]*\s\s>","<\s\s/cond>",function(w,s){\n var lookaheadMatch = config.macros.conditionalDisplay.lookaheadRegExp.exec( s [ 0 ] );\n if(lookaheadMatch ) {\n if( window.eval( lookaheadMatch [ 1 ] ) ) {\n wikify( s [ 1 ], w.output, null, w.tiddler );\n }\n }\n}));\n//}}}