Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
/***
|''Name:''|AccordionMenuPlugin|
|''Description:''|Turn an unordered list into an accordion style menu|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#AccordionMenuPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.0|
|''Date:''|03/11/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.5|
!!Usage:
* put {{{<<accordion>>}}} on the line after your unordered list
!!Customizing:
* customize the css via the shadow tiddler StyleSheetAccordionMenuPlugin
* or give the list a custom class by passing the classes as parameters to the macro.
** Eg: {{{<<accordion ClassName1 ClassName2>>}}}
!!Examples:
*[[AccordionMenuPluginDemo]]
***/
// /%
//!BEGIN-PLUGIN-CODE
config.macros.accordion={
dropchar : " \u00BB",
handler : function(place,macroName,params,wikifier,paramString,tiddler){
list = findRelated(place.lastChild,"UL","tagName","previousSibling");
if (!list)
return;
addClass(list,"accordion");
if (params.length){
addClass(list,paramString);
}
this.fixLinks(list.childNodes);
},
fixLinks : function(els){
for (var i=0; i<els.length; i++){
if(els[i].tagName.toLowerCase()=="li"){
var link = findRelated(els[i].firstChild,"A","tagName","nextSibling");
if(!link){
var ih = els[i].firstChild.data;
els[i].removeChild(els[i].firstChild);
link = createTiddlyElement(null,"a",null,null,ih+this.dropchar,{href:"javascript:;"});
els[i].insertBefore(link,els[i].firstChild);
}
else{
link.firstChild.data = link.firstChild.data + this.dropchar;
removeClass(link,"tiddlyLinkNonExisting");
}
link.onclick = this.show;
}
}
},
show : function(e){
var list = this.parentNode.parentNode;
var els = list.childNodes;
for (var i=0; i<els.length; i++){
removeClass(els[i],"accordion-active");
}
addClass(this.parentNode,"accordion-active");
}
};
config.shadowTiddlers["StyleSheetAccordionMenuPlugin"] = "/*{{{*/\n"+
"ul.accordion, ul.accordion li, ul.accordion li ul {margin:0; padding:0; list-style-type:none;text-align:left;}\n"+
"ul.accordion li ul {display:none;}\n"+
"ul.accordion li.accordion-active ul {display:block;}\n"+
"\n"+
"ul.accordion li.accordion-active a {cursor:default;}\n"+
"ul.accordion li.accordion-active ul li a{cursor:pointer;}\n"+
"\n"+
"ul.accordion a {display:block; padding:0.5em;}\n"+
"ul.accordion li a.tiddlyLink, ul.accordion li a.tiddlyLinkNonExisting, ul.accordion li a {font-weight:bold;}\n"+
"ul.accordion li a {background:#0066aa; color:#FFF; border-bottom:1px solid #fff;}\n"+
"ul.accordion li.accordion-active a, ul.accordion li a:hover {background:#00558F;color:#FFF;}\n"+
"\n"+
"ul.accordion li ul li{display:inline-block;overflow:hidden;}\n"+
"ul.accordion li.accordion-active ul li {background:#eff3fa; color:#000; padding:0em;}\n"+
"ul.accordion li.accordion-active ul li div {padding:1em 1.5em; background:#eff3fa;}\n"+
"ul.accordion li.accordion-active ul a{background:#eff3fa; color:#000; padding:0.5em 0.5em 0.5em 1.0em;border:none;}\n"+
"ul.accordion li.accordion-active ul a:hover {background:#e0e8f5; color:#000;}\n" +
"/*}}}*/";
store.addNotification("StyleSheetAccordionMenuPlugin",refreshStyles);
//!END-PLUGIN-CODE
// %/
@@display:none;clear:both;@@
''Creating a navigation menu using the AccordionMenuPlugin is as simple as:''
# writing a two level unordered list using ~TiddlyWiki syntax
# and placing {{{<<accordion>>}}} on the line after it.
Example:
{{{
* Section 1
** [[Link1]]
** [[Link2]]
** [[Link3]]
*Section 2
** [[Link4]]
** [[Link5]]
** [[Link6]]
*Section 3
**[[Link7]]
**[[Link8]]
**[[Link9]]
<<accordion>>
}}}
gives:
* Section 1
** [[Link1]]
** [[Link2]]
** [[Link3]]
*Section 2
** [[Link4]]
** [[Link5]]
** [[Link6]]
*Section 3
**[[Link7]]
**[[Link8]]
**[[Link9]]
<<accordion>>
''The AccordionMenuPlugin was written with navigation menu's in mind but can be put to other uses as well. ''
By wrapping the content in a DIV, you can have multi-line content as well. Example:
{{{
* [[section1]]
**{{myclass{
Praesent posuere sodales tortor. Mauris ut erat non lacus semper porta. Mauris enim.
Phasellus tempor, metus ut dapibus lobortis, leo magna ornare metus, et pellentesque neque massa eget turpis.
Proin nec tellus. Donec aliquet.
Nullam sed leo bibendum justo rutrum rhoncus.}}}
* section2
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
* section3
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
}}}
gives you:
* [[section1]]
**{{myclass{
Praesent posuere sodales tortor. Mauris ut erat non lacus semper porta. Mauris enim.
Phasellus tempor, metus ut dapibus lobortis, leo magna ornare metus, et pellentesque neque massa eget turpis.
Proin nec tellus. Donec aliquet.
Nullam sed leo bibendum justo rutrum rhoncus.}}}
* section2
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
* section3
**{{myclass{
Donec rhoncus sem eget urna.
Aenean tempor dolor vitae nisi.
Donec leo urna, placerat porttitor, auctor ut, volutpat a, purus,
Etiam eu sapien id nulla malesuada scelerisque.
Maecenas rhoncus, nibh ut aliquam consequat, mi odio luctus sem, eu lobortis dolor neque nec lectus. }}}
<<accordion>>
I'm writing articles for music- and computer-magazines:
* Muzikus
* MusicStore
* MujMac
* Click!
Background: #Fff
Foreground: #000
PrimaryPale: #fc8
PrimaryLight: #6CF
PrimaryMid: #38D
PrimaryDark: #000
SecondaryPale: #fc8
SecondaryLight: #def
SecondaryMid: #6CF
SecondaryDark: #000
TertiaryPale: #eee
TertiaryLight: #ddd
TertiaryMid: #ccc
TertiaryDark: #888
Error: #f88
*<<closeAll>>
*<<permaview>>
*<<newTiddler>>
*<<newJournal "DD. MMM YYYY" "journal">>
*<<saveChanges>>
*<<popup options [[<<tiddler OptionsPanel$))]]>>
|!Plugin|!Description|!Source|
|HTMLFormattingPlugin|Embed wiki syntax formatting inside of HTML content|[[http://www.TiddlyTools.com|http://www.TiddlyTools.com/#HTMLFormattingPlugin]]|
|GotoPlugin|View any tiddler by entering it's title - displays list of possible matches|[[http://www.tiddlytools.com|http://www.tiddlytools.com/#GotoPlugin]]|
|LessBackupsPlugin|Intelligently limit the number of backup files you create|http://lessbackupsplugin.tiddlyspot.com/|
|TaggerPlugin|Provides a drop down listing current tiddler tags, and allowing toggling of tags|[[http://tw.lewcid.org|http://tw.lewcid.org//#TaggerPlugin]]|
|PopupMacro|Create popups with custom content|http://tw.lewcid.org/#PopupMacro|
<html>
<iframe src="http://www.blueboard.cz/mailform.php?id=158728" frameborder="0" height="140" scrolling="no" width="330"></iframe>
</html>
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};
//--
//-- Crypto functions and associated conversion routines
//--
// Crypto "namespace"
function Crypto() {}
// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
var be = Array();
var len = Math.floor(str.length/4);
var i, j;
for(i=0, j=0; i<len; i++, j+=4) {
be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
}
while (j<str.length) {
be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
j++;
}
return be;
};
// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
var str = "";
for(var i=0;i<be.length*32;i+=8)
str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
return str;
};
// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
var hex = "0123456789ABCDEF";
var str = "";
for(var i=0;i<be.length*4;i++)
str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
return str;
};
// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
return Crypto.be32sToHex(Crypto.sha1Str(str));
};
// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
// Add 32-bit integers, wrapping at 32 bits
add32 = function(a,b)
{
var lsw = (a&0xFFFF)+(b&0xFFFF);
var msw = (a>>16)+(b>>16)+(lsw>>16);
return (msw<<16)|(lsw&0xFFFF);
};
// Add five 32-bit integers, wrapping at 32 bits
add32x5 = function(a,b,c,d,e)
{
var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
return (msw<<16)|(lsw&0xFFFF);
};
// Bitwise rotate left a 32-bit integer by 1 bit
rol32 = function(n)
{
return (n>>>31)|(n<<1);
};
var len = blen*8;
// Append padding so length in bits is 448 mod 512
x[len>>5] |= 0x80 << (24-len%32);
// Append length
x[((len+64>>9)<<4)+15] = len;
var w = Array(80);
var k1 = 0x5A827999;
var k2 = 0x6ED9EBA1;
var k3 = 0x8F1BBCDC;
var k4 = 0xCA62C1D6;
var h0 = 0x67452301;
var h1 = 0xEFCDAB89;
var h2 = 0x98BADCFE;
var h3 = 0x10325476;
var h4 = 0xC3D2E1F0;
for(var i=0;i<x.length;i+=16) {
var j,t;
var a = h0;
var b = h1;
var c = h2;
var d = h3;
var e = h4;
for(j = 0;j<16;j++) {
w[j] = x[i+j];
t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=16;j<20;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=20;j<40;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=40;j<60;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=60;j<80;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
h0 = add32(h0,a);
h1 = add32(h1,b);
h2 = add32(h2,c);
h3 = add32(h3,d);
h4 = add32(h4,e);
}
return Array(h0,h1,h2,h3,h4);
};
}
//}}}
/***
<<option chkNoHeader>> hide header
***/
//{{{
merge(config.messages.messageClose,{text: "X",tooltip: "close this message area"});
if (config.options.chkNoHeader) setStylesheet(".headerForeground,.headerShadow,#mainToolbar{display:none}","noHeader");
config.options.txtExternalizeProccessing = "ExternalizeAsHTML";
//}}}
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};
//--
//-- Deprecated code
//--
// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};
// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = function(w)
{
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var text = lookaheadMatch[1];
if(config.browser.isIE)
text = text.replace(/\n/g,"\r");
createTiddlyElement(w.output,"pre",null,null,text);
w.nextMatch = lookaheadRegExp.lastIndex;
}
};
// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
createTiddlyElement(place,"br");
};
// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
var i = this.indexOf(item);
return i == -1 ? null : i;
};
// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
return store.getLoader().internalizeTiddler(store,this,title,divRef);
};
// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
return store.getSaver().externalizeTiddler(store,this);
};
// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
return store.allTiddlersAsHtml();
}
// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
refreshPageTemplate(title);
}
// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
story.displayTiddlers(srcElement,titles,template,animate);
}
// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
story.displayTiddler(srcElement,title,template,animate);
}
// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;
// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");
}
//}}}
/***
|''Name:''|DisableWikiLinksPlugin|
|''Description:''|Allows you to disable TiddlyWiki's automatic linking of WikiWords|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#DisableWikiLinksPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/DisableWikiLinksPlugin.js |
|''Version:''|0.1.3|
|''Date:''|Aug 5, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|
|''Disable WikiLinks''|<<option chkDisableWikiLinks>>|
***/
//{{{
// Ensure that the DisableWikiLinksPlugin is only installed once.
if(!version.extensions.DisableWikiLinksPlugin) {
version.extensions.DisableWikiLinksPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('DisableWikiLinksPlugin requires TiddlyWiki 2.1 or newer.');}
if (config.options.chkDisableWikiLinks==undefined)
{config.options.chkDisableWikiLinks = false;}
Tiddler.prototype.autoLinkWikiWords = function()
{
if(config.options.chkDisableWikiLinks==true)
{return false;}
return !this.isTagged('systemConfig') && !this.isTagged('excludeMissing');
};
} // end of 'install only once'
//}}}
{{justify{''//TiddlyTools plugins, scripts, templates, styles, etc, are [[licensed|LegalStatements]] for use by the general public without any charges or fees.//'' Even so, a considerable amount of effort and creativity has been applied to developing and maintaining these add-on components as well as the FAQ articles, examples, and other content presented in this document. In addition, much time has been dedicated to providing support to the TiddlyWiki user community by responding to questions and requests for help posted online or sent by private email.
//If TiddlyTools' add-ons, articles, examples, or help responses have been of use to you, and you'd like to show your appreciation in a tangible way, you can make a financial donation via [[PayPal|http://www.PayPal.com/]].//
{{smallform fine{<html><hide linebreaks><div style='float:right;margin-left:1em;'>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank" style="padding:0;margin:0;">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="elsdesign@gmail.com">
<input type="hidden" name="item_name" value="TiddlyTools Donation">
<input type="hidden" name="no_shipping" value="0">
<input type="hidden" name="cn" value="Your feedback is appreciated!">
<input type="hidden" name="tax" value="0">
<input type="hidden" name="lc" value="US">
<input type="hidden" name="bn" value="PP-DonationsBF">
<table class="borderless"><tr valign="bottom"><td>
<i>amount</i><br>
<input type="text" value="" name="amount" maxlength="16" size="10" id="amount"/>
</td><td>
<i>currency</i><br>
<select name="currency_code">
<option value="AUD">Australian Dollars</option>
<option value="CAD">Canadian Dollars</option>
<option value="EUR">Euros</option>
<option value="GBP">Pounds Sterling</option>
<option selected="selected" value="USD">US Dollars</option>
<option value="JPY">Yen</option>
</select>
</td><td>
<input type="submit" name="submit" value="Make a Donation">
</td></tr></table>
</form></div></html>}}}{{center{''//You decide how much TiddlyTools has been worth to you.//... simply give what you feel is fair reward for the value you have received.''}}}
{{clear fine{
//Please note: In addition to saying "thank you", your donations will enable me to devote more time to maintaining and enhancing the components offered on TiddlyTools as well as continue to provide ongoing help and support activities for the general TiddlyWiki community at large... so ''please donate generously and often!''//}}}}}}
''horizontal:''
{{{
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
* menu #3
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu>>
}}}
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
* menu #3
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu>>
''vertical:''
{{{
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu vertical>>
}}}
* menu #1
** [[item #1-1]]
** [[item #1-2]]
** [[item #1-3]]
* menu #2
** [[item #2-1]]
** [[item #2-2]]
** [[menu #2-3]]
<<dropMenu vertical>>
/% %/
/***
|''Name:''|DropDownMenuPlugin|
|''Description:''|Create dropdown menus from unordered lists|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#DropDownMenuPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|11/04/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.5|
!!Usage:
* create a two-level unordered list using wiki syntax, and place {{{<<dropMenu>>}}} on the line after it.
* to create a vertical menu use {{{<<dropMenu vertical>>}}} instead.
* to assign custom classes to the list, just pass them as parameters to the macro {{{<<dropMenu className1 className2 className3>>}}}
!!Features:
*Supports just a single level of drop-downs, as anything more usually provides a poor experience for the user.
* Very light weight, about 1.5kb of JavaScript and 4kb of CSS.
* Comes with two built in css 'themes', the default horizontal and vertical.
!!Customizing:
* to customize the appearance of the menu's, you can either add a custom class as described above or, you can edit the CSS via the StyleSheetDropDownMenu shadow tiddler.
!!Examples:
* [[DropDownMenuDemo]]
***/
// /%
//!BEGIN-PLUGIN-CODE
config.macros.dropMenu={
dropdownchar: "\u25bc",
handler : function(place,macroName,params,wikifier,paramString,tiddler){
list = findRelated(place.lastChild,"UL","tagName","previousSibling");
if (!list)
return;
addClass(list,"suckerfish");
if (params.length){
addClass(list,paramString);
}
this.fixLinks(list);
},
fixLinks : function(el){
var els = el.getElementsByTagName("li");
for(var i = 0; i < els.length; i++) {
if(els[i].getElementsByTagName("ul").length>0){
var link = findRelated(els[i].firstChild,"A","tagName","nextSibling");
if(!link){
var ih = els[i].firstChild.data;
els[i].removeChild(els[i].firstChild);
var d = createTiddlyElement(null,"a",null,null,ih+this.dropdownchar,{href:"javascript:;"});
els[i].insertBefore(d,els[i].firstChild);
}
else{
link.firstChild.data = link.firstChild.data + this.dropdownchar;
removeClass(link,"tiddlyLinkNonExisting");
}
}
els[i].onmouseover = function() {
addClass(this, "sfhover");
};
els[i].onmouseout = function() {
removeClass(this, "sfhover");
};
}
}
};
config.shadowTiddlers["StyleSheetDropDownMenuPlugin"] =
"/*{{{*/\n"+
"/***** LAYOUT STYLES - DO NOT EDIT! *****/\n"+
"ul.suckerfish, ul.suckerfish ul {\n"+
" margin: 0;\n"+
" padding: 0;\n"+
" list-style: none;\n"+
" line-height:1.4em;\n"+
"}\n\n"+
"ul.suckerfish li {\n"+
" display: inline-block; \n"+
" display: block;\n"+
" float: left; \n"+
"}\n\n"+
"ul.suckerfish li ul {\n"+
" position: absolute;\n"+
" left: -999em;\n"+
"}\n\n"+
"ul.suckerfish li:hover ul, ul.suckerfish li.sfhover ul {\n"+
" left: auto;\n"+
"}\n\n"+
"ul.suckerfish ul li {\n"+
" float: none;\n"+
" border-right: 0;\n"+
" border-left:0;\n"+
"}\n\n"+
"ul.suckerfish a, ul.suckerfish a:hover {\n"+
" display: block;\n"+
"}\n\n"+
"ul.suckerfish li a.tiddlyLink, ul.suckerfish li a, #mainMenu ul.suckerfish li a {font-weight:bold;}\n"+
"/**** END LAYOUT STYLES *****/\n"+
"\n\n"+
"/**** COLORS AND APPEARANCE - DEFAULT *****/\n"+
"ul.suckerfish li a {\n"+
" padding: 0.5em 1.5em;\n"+
" color: #FFF;\n"+
" background: #0066aa;\n"+
" border-bottom: 0;\n"+
" font-weight:bold;\n"+
"}\n\n"+
"ul.suckerfish li:hover a, ul.suckerfish li.sfhover a{\n"+
" background: #00558F;\n"+
"}\n\n"+
"ul.suckerfish li:hover ul a, ul.suckerfish li.sfhover ul a{\n"+
" color: #000;\n"+
" background: #eff3fa;\n"+
" border-top:1px solid #FFF;\n"+
"}\n\n"+
"ul.suckerfish ul li a:hover {\n"+
" background: #e0e8f5;\n"+
"}\n\n"+
"ul.suckerfish li a{\n"+
" width:9em;\n"+
"}\n\n"+
"ul.suckerfish ul li a, ul.suckerfish ul li a:hover{\n"+
" display:inline-block;\n"+
" width:9em;\n"+
"}\n\n"+
"ul.suckerfish li {\n"+
" border-left: 1px solid #00558F;\n"+
"}\n"+
"/***** END COLORS AND APPEARANCE - DEFAULT *****/\n"+
"\n\n"+
"/***** LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
"ul.suckerfish.vertical li{\n"+
" width:10em;\n"+
" border-left: 0px solid #00558f;\n"+
"}\n\n"+
"ul.suckerfish.vertical ul li, ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a {\n"+
" border-left: 0.8em solid #00558f;\n"+
"}\n\n"+
"ul.suckerfish.vertical li a, ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a, ul.suckerfish.vertical li.sfhover a:hover{\n"+
" width:8em;\n"+
"}\n\n"+
"ul.suckerfish.vertical {\n"+
" width:10em; text-align:left;\n"+
" float:left;\n"+
"}\n\n"+
"ul.suckerfish.vertical li a {\n"+
" padding: 0.5em 1em 0.5em 1em;\n"+
" border-top:1px solid #fff;\n"+
"}\n\n"+
"ul.suckerfish.vertical, ul.suckerfish.vertical ul {\n"+
" line-height:1.4em;\n"+
"}\n\n"+
"ul.suckerfish.vertical li:hover ul, ul.suckerfish.vertical li.sfhover ul { \n"+
" margin: -2.4em 0 0 10.9em;\n"+
"}\n\n"+
"ul.suckerfish.vertical li:hover ul li a, ul.suckerfish.vertical li.sfhover ul li a {\n"+
" border: 0px solid #FFF;\n"+
"}\n\n"+
"ul.suckerfish.vertical li:hover a, ul.suckerfish.vertical li.sfhover a{\n"+
" padding-right:1.1em;\n"+
"}\n\n"+
"ul.suckerfish.vertical li:hover ul li, ul.suckerfish.vertical li.sfhover ul li {\n"+
" border-bottom:1px solid #fff;\n"+
"}\n\n"+
"/***** END LAYOUT AND APPEARANCE: VERTICAL *****/\n"+
"/*}}}*/";
store.addNotification("StyleSheetDropDownMenuPlugin",refreshStyles);
//!END-PLUGIN-CODE
// %/
/*{{{*/
body {color:#444; font-size:0.75em;line-height:1.4em;font-family:arial,helvetica;margin : 0.5em; padding : 0;}
html {border:0}
a, a:link, a:visited, a:active {text-decoration:none;color:#BB4400;font-weight:bold}
ul, ol {margin-left:0.5em;padding-left:1.5em;}
/*}}}*/
/***
|''Name:''|EasyEditPlugin|
|''Description:''|Lite and extensible Wysiwyg editor for TiddlyWiki.|
|''Version:''|1.3.3|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0|
!Demo
*On the plugin [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], see [[WysiwygDemo]] and use the {{{write}}} button.
!Installation
#import the plugin,
#save and reload,
#use the <<toolbar easyEdit>> button in the tiddler's toolbar (in default ViewTemplate) or add {{{easyEdit}}} command in your own toolbar.
! Useful Addons
*[[HTMLFormattingPlugin|http://www.tiddlytools.com/#HTMLFormattingPlugin]] to embed wiki syntax in html tiddlers.<<br>>//__Tips__ : When this plugin is installed, you can use anchor syntax to link tiddlers in wysiwyg mode (example : #example). Anchors are converted back and from wiki syntax when editing.//
*[[TaggedTemplateTweak|http://www.TiddlyTools.com/#TaggedTemplateTweak]] to use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values.
!Configuration
|Buttons in the toolbar (empty = all).<<br>>//Example : bold,underline,separator,forecolor//<<br>>The buttons will appear in this order.| <<option txtEasyEditorButtons>>|
|EasyEditor default height | <<option txtEasyEditorHeight>>|
|Stylesheet applied to the edited richtext |[[EasyEditDocStyleSheet]]|
|Template called by the {{{write}}} button |[[EasyEditTemplate]]|
!How to extend EasyEditor
*To add your own buttons, add some code like the following in a systemConfig tagged tiddler (//use the prompt attribute only if there is a parameter//) :
**{{{EditorToolbar.buttons.heading = {label:"H", toolTip : "Set heading level", prompt: "Enter heading level"};}}}
**{{{EditorToolbar.buttonsList +=",heading";}}}
*To get the list of all possible commands, see the documentation of the [[Gecko built-in rich text editor|http://developer.mozilla.org/en/docs/Midas]] or the [[IE command identifiers|http://msdn2.microsoft.com/en-us/library/ms533049.aspx]].
*To go further in customization, see [[Link button|EasyEditPlugin-LinkButton]] as an example.
!Code
***/
//{{{
var geckoEditor={};
var IEeditor={};
config.options.txtEasyEditorHeight = config.options.txtEasyEditorHeight ? config.options.txtEasyEditorHeight : "500px";
config.options.txtEasyEditorButtons = config.options.txtEasyEditorButtons ? config.options.txtEasyEditorButtons : "";
// TW2.1.x compatibility
config.browser.isGecko = config.browser.isGecko ? config.browser.isGecko : (config.userAgent.indexOf("gecko") != -1);
config.macros.annotations = config.macros.annotations ? config.macros.annotations : {handler : function() {}}
// EASYEDITOR MACRO
config.macros.easyEdit = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var field = params[0];
var height = params[1] ? params[1] : config.options.txtEasyEditorHeight;
var editor = field ? new easyEditor(tiddler,field,place,height) : null;
},
gather: function(element){
var iframes = element.getElementsByTagName("iframe");
if (iframes.length!=1) return null
var text = "<html>"+iframes[0].contentWindow.document.body.innerHTML+"</html>";
text = config.browser.isGecko ? geckoEditor.postProcessor(text) : (config.browser.isIE ? IEeditor.postProcessor(text) : text);
return text;
}
}
// EASYEDITOR CLASS
function easyEditor(tiddler,field,place,height) {
this.tiddler = tiddler;
this.field = field;
this.browser = config.browser.isGecko ? geckoEditor : (config.browser.isIE ? IEeditor : null);
this.wrapper = createTiddlyElement(place,"div",null,"easyEditor");
this.wrapper.setAttribute("easyEdit",this.field);
this.iframe = createTiddlyElement(null,"iframe");
this.browser.setupFrame(this.iframe,height,contextualCallback(this,this.onload));
this.wrapper.appendChild(this.iframe);
}
easyEditor.prototype.onload = function(){
this.editor = this.iframe.contentWindow;
this.doc = this.editor.document;
if (!this.browser.isDocReady(this.doc)) return null;
if (!this.tiddler.isReadOnly() && this.doc.designMode.toLowerCase()!="on") {
this.doc.designMode = "on";
if (this.browser.reloadOnDesignMode) return false; // IE fire readystatechange after designMode change
}
var internalCSS = store.getTiddlerText("EasyEditDocStyleSheet");
setStylesheet(internalCSS,"EasyEditDocStyleSheet",this.doc);
this.browser.initContent(this.doc,store.getValue(this.tiddler,this.field));
var barElement=createTiddlyElement(null,"div",null,"easyEditorToolBar");
this.wrapper.insertBefore(barElement,this.wrapper.firstChild);
this.toolbar = new EditorToolbar(this.doc,barElement,this.editor);
this.browser.plugEvents(this.doc,contextualCallback(this,this.scheduleButtonsRefresh));
this.editor.focus();
}
easyEditor.SimplePreProcessoror = function(text) {
var re = /^<html>(.*)<\/html>$/m;
var htmlValue = re.exec(text);
var value = (htmlValue && (htmlValue.length>0)) ? htmlValue[1] : text;
return value;
}
easyEditor.prototype.scheduleButtonsRefresh=function() { //doesn't refresh buttons state when rough typing
if (this.nextUpdate) window.clearTimeout(this.nextUpdate);
this.nextUpdate = window.setTimeout(contextualCallback(this.toolbar,EditorToolbar.onUpdateButton),easyEditor.buttonDelay);
}
easyEditor.buttonDelay = 200;
// TOOLBAR CLASS
function EditorToolbar(target,parent,window){
this.target = target;
this.window=window;
this.elements={};
var row = createTiddlyElement(createTiddlyElement(createTiddlyElement(parent,"table"),"tbody"),"tr");
var buttons = (config.options.txtEasyEditorButtons ? config.options.txtEasyEditorButtons : EditorToolbar.buttonsList).split(",");
for(var cpt = 0; cpt < buttons.length; cpt++){
var b = buttons[cpt];
var button = EditorToolbar.buttons[b];
if (button) {
if (button.separator)
createTiddlyElement(row,"td",null,"separator").innerHTML+=" ";
else {
var cell=createTiddlyElement(row,"td",null,b+"Button");
if (button.onCreate) button.onCreate.call(this, cell, b);
else EditorToolbar.createButton.call(this, cell, b);
}
}
}
}
EditorToolbar.createButton = function(place,name){
this.elements[name] = createTiddlyButton(place,EditorToolbar.buttons[name].label,EditorToolbar.buttons[name].toolTip,contextualCallback(this,EditorToolbar.onCommand(name)),"button");
}
EditorToolbar.onCommand = function(name){
var button = EditorToolbar.buttons[name];
return function(){
var parameter = false;
if (button.prompt) {
var parameter = this.target.queryCommandValue(name);
parameter = prompt(button.prompt,parameter);
}
if (parameter != null) {
this.target.execCommand(name, false, parameter);
EditorToolbar.onUpdateButton.call(this);
}
return false;
}
}
EditorToolbar.getCommandState = function(target,name){
try {return target.queryCommandState(name)}
catch(e){return false}
}
EditorToolbar.onRefreshButton = function (name){
if (EditorToolbar.getCommandState(this.target,name)) addClass(this.elements[name].parentNode,"buttonON");
else removeClass(this.elements[name].parentNode,"buttonON");
this.window.focus();
}
EditorToolbar.onUpdateButton = function(){
for (b in this.elements)
if (EditorToolbar.buttons[b].onRefresh) EditorToolbar.buttons[b].onRefresh.call(this,b);
else EditorToolbar.onRefreshButton.call(this,b);
}
EditorToolbar.buttons = {
separator : {separator : true},
bold : {label:"B", toolTip : "Bold"},
italic : {label:"I", toolTip : "Italic"},
underline : {label:"U", toolTip : "Underline"},
strikethrough : {label:"S", toolTip : "Strikethrough"},
insertunorderedlist : {label:"\u25CF", toolTip : "Unordered list"},
insertorderedlist : {label:"1.", toolTip : "Ordered list"},
justifyleft : {label:"[\u2261", toolTip : "Align left"},
justifyright : {label:"\u2261]", toolTip : "Align right"},
justifycenter : {label:"\u2261", toolTip : "Align center"},
justifyfull : {label:"[\u2261]", toolTip : "Justify"},
removeformat : {label:"\u00F8", toolTip : "Remove format"},
fontsize : {label:"\u00B1", toolTip : "Set font size", prompt: "Enter font size"},
forecolor : {label:"C", toolTip : "Set font color", prompt: "Enter font color"},
fontname : {label:"F", toolTip : "Set font name", prompt: "Enter font name"},
heading : {label:"H", toolTip : "Set heading level", prompt: "Enter heading level (example : h1, h2, ...)"},
indent : {label:"\u2192[", toolTip : "Indent paragraph"},
outdent : {label:"[\u2190", toolTip : "Outdent paragraph"},
inserthorizontalrule : {label:"\u2014", toolTip : "Insert an horizontal rule"},
insertimage : {label:"\u263C", toolTip : "Insert image", prompt: "Enter image url"}
}
EditorToolbar.buttonsList = "bold,italic,underline,strikethrough,separator,increasefontsize,decreasefontsize,fontsize,forecolor,fontname,separator,removeformat,separator,insertparagraph,insertunorderedlist,insertorderedlist,separator,justifyleft,justifyright,justifycenter,justifyfull,indent,outdent,separator,heading,separator,inserthorizontalrule,insertimage";
if (config.browser.isGecko) {
EditorToolbar.buttons.increasefontsize = {onCreate : EditorToolbar.createButton, label:"A", toolTip : "Increase font size"};
EditorToolbar.buttons.decreasefontsize = {onCreate : EditorToolbar.createButton, label:"A", toolTip : "Decrease font size"};
EditorToolbar.buttons.insertparagraph = {label:"P", toolTip : "Format as paragraph"};
}
// GECKO (FIREFOX, ...) BROWSER SPECIFIC METHODS
geckoEditor.setupFrame = function(iframe,height,callback) {
iframe.setAttribute("style","width: 100%; height:" + height);
iframe.addEventListener("load",callback,true);
}
geckoEditor.plugEvents = function(doc,onchange){
doc.addEventListener("keyup", onchange, true);
doc.addEventListener("keydown", onchange, true);
doc.addEventListener("click", onchange, true);
}
geckoEditor.postProcessor = function(text){return text};
geckoEditor.preProcessor = function(text){return easyEditor.SimplePreProcessoror(text)}
geckoEditor.isDocReady = function() {return true;}
geckoEditor.reloadOnDesignMode=false;
geckoEditor.initContent = function(doc,content){
if (content) doc.execCommand("insertHTML",false,geckoEditor.preProcessor(content));
}
// INTERNET EXPLORER BROWSER SPECIFIC METHODS
IEeditor.setupFrame = function(iframe,height,callback) {
iframe.width="99%"; //IE displays the iframe at the bottom if 100%. CSS layout problem ? I don't know. To be studied...
iframe.height=height.toString();
iframe.attachEvent("onreadystatechange",callback);
}
IEeditor.plugEvents = function(doc,onchange){
doc.attachEvent("onkeyup", onchange);
doc.attachEvent("onkeydown", onchange);
doc.attachEvent("onclick", onchange);
}
IEeditor.isDocReady = function(doc){
if (doc.readyState!="complete") return false;
if (!doc.body) return false;
return (doc && doc.getElementsByTagName && doc.getElementsByTagName("head") && doc.getElementsByTagName("head").length>0);
}
IEeditor.postProcessor = function(text){return text};
IEeditor.preProcessor = function(text){return easyEditor.SimplePreProcessoror(text)}
IEeditor.reloadOnDesignMode=true;
IEeditor.initContent = function(doc,content){
if (content) doc.body.innerHTML=IEeditor.preProcessor(content);
}
function contextualCallback(obj,func){
return function(){return func.call(obj)}
}
Story.prototype.previousGatherSaveEasyEdit = Story.prototype.previousGatherSaveEasyEdit ? Story.prototype.previousGatherSaveEasyEdit : Story.prototype.gatherSaveFields; // to avoid looping if this line is called several times
Story.prototype.gatherSaveFields = function(e,fields){
if(e && e.getAttribute) {
var f = e.getAttribute("easyEdit");
if(f){
var newVal = config.macros.easyEdit.gather(e);
if (newVal) fields[f] = newVal;
}
this.previousGatherSaveEasyEdit(e, fields);
}
}
config.commands.easyEdit={
text: "write",
tooltip: "Edit this tiddler in wysiwyg mode",
readOnlyText: "view",
readOnlyTooltip: "View the source of this tiddler",
handler : function(event,src,title) {
clearMessage();
var tiddlerElem = document.getElementById(story.idPrefix + title);
var fields = tiddlerElem.getAttribute("tiddlyFields");
story.displayTiddler(null,title,"EasyEditTemplate",false,null,fields);
return false;
}
}
config.shadowTiddlers.ViewTemplate = config.shadowTiddlers.ViewTemplate.replace(/\+editTiddler/,"+editTiddler easyEdit");
config.shadowTiddlers.EasyEditTemplate = config.shadowTiddlers.EditTemplate.replace(/macro='edit text'/,"macro='easyEdit text'");
config.shadowTiddlers.EasyEditToolBarStyleSheet = "/*{{{*/\n";
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar {font-size:0.8em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".editor iframe {border:1px solid #DDD}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar td{border:1px solid #888; padding:2px 1px 2px 1px; vertical-align:middle}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar td.separator{border:0}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .button{border:0;color:#444}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .buttonON{background-color:#EEE}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar {margin:0.25em 0}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .boldButton {font-weight:bold}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .italicButton .button {font-style:italic;padding-right:0.65em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .underlineButton .button {text-decoration:underline}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .strikeButton .button {text-decoration:line-through}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .unorderedListButton {margin-left:0.7em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .justifyleftButton .button {padding-left:0.1em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .justifyrightButton .button {padding-right:0.1em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .justifyfullButton .button, .easyEditorToolBar .indentButton .button, .easyEditorToolBar .outdentButton .button {padding-left:0.1em;padding-right:0.1em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .increasefontsizeButton .button {padding-left:0.15em;padding-right:0.15em; font-size:1.3em; line-height:0.75em}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .decreasefontsizeButton .button {padding-left:0.4em;padding-right:0.4em; font-size:0.8em;}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .forecolorButton .button {color:red;}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet += ".easyEditorToolBar .fontnameButton .button {font-family:serif}\n" ;
config.shadowTiddlers.EasyEditToolBarStyleSheet +="/*}}}*/";
store.addNotification("EasyEditToolBarStyleSheet", refreshStyles);
config.shadowTiddlers.EasyEditDocStyleSheet = "/*{{{*/\n \n/*}}}*/";
if (config.annotations) config.annotations.EasyEditDocStyleSheet = "This stylesheet is applied when editing a text with the wysiwyg easyEditor";
//}}}
/***
!Link button add-on
***/
//{{{
EditorToolbar.createLinkButton = function(place,name) {
this.elements[name] = createTiddlyButton(place,EditorToolbar.buttons[name].label,EditorToolbar.buttons[name].toolTip,contextualCallback(this,EditorToolbar.onInputLink()),"button");
}
EditorToolbar.onInputLink = function() {
return function(){
var browser = config.browser.isGecko ? geckoEditor : (config.browser.isIE ? IEeditor : null);
var value = browser ? browser.getLink(this.target) : "";
value = prompt(EditorToolbar.buttons["createlink"].prompt,value);
if (value) browser.doLink(this.target,value);
else if (value=="") this.target.execCommand("unlink", false, value);
EditorToolbar.onUpdateButton.call(this);
return false;
}
}
EditorToolbar.buttonsList += ",separator,createlink";
EditorToolbar.buttons.createlink = {onCreate : EditorToolbar.createLinkButton, label:"L", toolTip : "Set link", prompt: "Enter link url"};
geckoEditor.getLink=function(doc){
var range=doc.defaultView.getSelection().getRangeAt(0);
var container = range.commonAncestorContainer;
var node = (container.nodeType==3) ? container.parentNode : range.startContainer.childNodes[range.startOffset];
if (node && node.tagName=="A") {
var r=doc.createRange();
r.selectNode(node);
doc.defaultView.getSelection().addRange(r);
return (node.getAttribute("tiddler") ? "#"+node.getAttribute("tiddler") : node.href);
}
else return (container.nodeType==3 ? "#"+container.textContent.substr(range.startOffset, range.endOffset-range.startOffset).replace(/ $/,"") : "");
}
geckoEditor.doLink=function(doc,link){ // store tiddler in a temporary attribute to avoid url encoding of tiddler's name
var pin = "href"+Math.random().toString().substr(3);
doc.execCommand("createlink", false, pin);
var isTiddler=(link.charAt(0)=="#");
var node = doc.defaultView.getSelection().getRangeAt(0).commonAncestorContainer;
var links= (node.nodeType!=3) ? node.getElementsByTagName("a") : [node.parentNode];
for (var cpt=0;cpt<links.length;cpt++)
if (links[cpt].href==pin){
links[cpt].href=isTiddler ? "javascript:;" : link;
links[cpt].setAttribute("tiddler",isTiddler ? link.substr(1) : "");
}
}
geckoEditor.beforeLinkPostProcessor = geckoEditor.beforelinkPostProcessor ? geckoEditor.beforelinkPostProcessor : geckoEditor.postProcessor;
geckoEditor.postProcessor = function(text){
return geckoEditor.beforeLinkPostProcessor(text).replace(/<a tiddler="([^"]*)" href="javascript:;">(.*?)(?:<\/a>)/gi,"[[$2|$1]]").replace(/<a tiddler="" href="/gi,'<a href="');
}
geckoEditor.beforeLinkPreProcessor = geckoEditor.beforeLinkPreProcessor ? geckoEditor.beforeLinkPreProcessor : geckoEditor.preProcessor
geckoEditor.preProcessor = function(text){
return geckoEditor.beforeLinkPreProcessor(text).replace(/\[\[([^|\]]*)\|([^\]]*)]]/g,'<a tiddler="$2" href="javascript:;">$1</a>');
}
IEeditor.getLink=function(doc){
var node=doc.selection.createRange().parentElement();
if (node.tagName=="A") return node.href;
else return (doc.selection.type=="Text"? "#"+doc.selection.createRange().text.replace(/ $/,"") :"");
}
IEeditor.doLink=function(doc,link){
doc.execCommand("createlink", false, link);
}
IEeditor.beforeLinkPreProcessor = IEeditor.beforeLinkPreProcessor ? IEeditor.beforeLinkPreProcessor : IEeditor.preProcessor
IEeditor.preProcessor = function(text){
return IEeditor.beforeLinkPreProcessor(text).replace(/\[\[([^|\]]*)\|([^\]]*)]]/g,'<a ref="#$2">$1</a>');
}
IEeditor.beforeLinkPostProcessor = IEeditor.beforelinkPostProcessor ? IEeditor.beforelinkPostProcessor : IEeditor.postProcessor;
IEeditor.postProcessor = function(text){
return IEeditor.beforeLinkPostProcessor(text).replace(/<a href="#([^>]*)">([^<]*)<\/a>/gi,"[[$2|$1]]");
}
IEeditor.beforeLinkInitContent = IEeditor.beforeLinkInitContent ? IEeditor.beforeLinkInitContent : IEeditor.initContent;
IEeditor.initContent = function(doc,content){
IEeditor.beforeLinkInitContent(doc,content);
var links=doc.body.getElementsByTagName("A");
for (var cpt=0; cpt<links.length; cpt++) {
links[cpt].href=links[cpt].ref; //to avoid IE conversion of relative URLs to absolute
links[cpt].removeAttribute("ref");
}
}
config.shadowTiddlers.EasyEditToolBarStyleSheet += "\n/*{{{*/\n.easyEditorToolBar .createlinkButton .button {color:blue;text-decoration:underline;}\n/*}}}*/";
config.shadowTiddlers.EasyEditDocStyleSheet += "\n/*{{{*/\na {color:#0044BB;font-weight:bold}\n/*}}}*/";
//}}}
/***
|''Name:''|EncryptedVaultPlugin|
|''Description:''|Adds RC4 encryption and password protection to tiddywiki.|
|''Version:''|1.0.1|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Description
*Create an ''encrypted vault'' where all tiddlers are ''password protected''.
*By default, only the system tiddlers aren't encrypted.
*Even shadow tiddlers (MainMenu, SiteTitle, PageTemplate, StyleSheet, ...) ''can be encrypted''. The shadow version is used until unlocking.
!Demo
Use <<unlock>> button on a protected wiki. By example : http://visualtw.ouvaton.org/demo/EncryptedVaultPlugin.html
!Installation
#Import the plugin (tagged as systemConfig)
#Save and reload
#Save once more time to create the encrypted vault
#Reload and set a password
!Usage
*Use <<unlock>><<setPassword>> button (available by default in SideBarOptions)
*Use a blank password to save unencrypted (disable vault usage)
*Use {{{unencrypted}}} tag to avoid encryption for some tiddler
*Use {{{forceEncryption}}} tag to force some shadow tiddler to be encrypted
!Configuration
The following macros are available :
*{{{<<unlock ButtonTitle ButtonTooltip OpenTiddlersWhenUnlock CloseTiddlersWhenUnlock>>}}} creates a button to unlock the encrypted vault (all parameters are optionnal)
*{{{<<setPassword ButtonTitle ButtonTooltip>>}}} if unlocked, creates a button to set the current password (all parameters are optionnal)
*{{{<<purge ButtonTitle ButtonTooltip>>}}} if locked, creates a button to purge a locked vault, useful for lost password (encrypted content is the deleted)
*{{{<<ifLocked tiddlyText>>}}} displays tiddlyText (wikified) if the vault is locked
*{{{<<ifUnlocked tiddlyText>>}}} displays tiddlyText (wikified) if the vault is unlocked
<<ifLocked "!!!!Lost password ?">><<ifLocked "Click on">> <<purge>><<ifLocked "to delete any content locked in the encrypted vault.">>
***/
//{{{
config.messages.vaultCreationInfo = "The encrypted vault has been created";
config.messages.purgeConfirm = "Purge the encrypted vault ?\n\nAll unlocked content will be lost.";
config.messages.vaultPurgedInfo = "All contents have been purged from encrypted vault.\nPassword has been blanked.\nYou must save once to apply this changes.";
config.messages.vaultEncryptedInfo = "Saving with encryption";
config.messages.vaultUnchangedInfo = "No changes in Encrypted vault";
config.messages.noLockedVaultWarning = "Unable to proceed. No locked encrypted vault.";
config.messages.emptyVaultInfo = "Saving without encryption";
config.messages.saveWithLockedVaultConfirm = "Encrypted vault is locked. No changes will apply inside.\n\nAre you sure ?";
config.messages.confirmOverload = "This following tiddler already exists in system store. Overload ?\nOK : the encrypted version will replace the system store version\nCancel : the system store version will replace the encrypted version";
SaverBase.systemStore="unencrypted";
SaverBase.vault="forceEncryption";
var startSaveVaultArea = '<div id="' + 'vaultArea">'; // Split up into two so that indexOf() of this source doesn't find it
var endSaveVaultArea = '</d' + 'iv>';
config.shadowTiddlers.SideBarOptions = config.shadowTiddlers.SideBarOptions.replace(/<<saveChanges>>/,"<<unlock>><<setPassword>><<saveChanges>>");
config.shadowTiddlers.GettingStarted+="\n\n<<ifLocked 'This TiddlyWiki use EncryptedVaultPlugin. To load protected content click on'>><<unlock>><<ifUnlocked 'This TiddlyWiki use EncryptedVaultPlugin. To set or change password click on'>><<setPassword>>"
window.updateOriginal= function(original,posDiv) // overriding the TW2.2 standard function
{
var vaultIsUpdatable = (!locateVaultArea(original) || !vault.isLocked() || vault.purge); // vault is new, unlocked or must be purged
if(!posDiv)
posDiv = locateStoreArea(original);
if(!posDiv) {
alert(config.messages.invalidFileError.format([localPath]));
return null;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
convertUnicodeToUTF8((vaultIsUpdatable && vault.password) ? store.allUnencryptedTiddlersAsHtml() : store.allTiddlersAsHtml()) + "\n" +
original.substr(posDiv[1]);
if (vaultIsUpdatable) {
posVault = locateVaultArea(original)
if(!posVault) {
revised=createVault(revised);
posVault = locateVaultArea(revised);
if(!posVault) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
}
var revised = revised.substr(0,posVault[0] + startSaveVaultArea.length) +
convertUnicodeToUTF8(vault.password ? vault.encrypt(store.allEncryptedTiddlersAsHtml()) : "") +
revised.substr(posVault[1]);
if (vault.password) displayMessage(config.messages.vaultEncryptedInfo);
else displayMessage(config.messages.emptyVaultInfo);
}
else displayMessage(config.messages.vaultUnchangedInfo);
var newSiteTitle = convertUnicodeToUTF8(getPageTitle()).htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateLanguageAttribute(revised);
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
}
function createVault(original) {
var revised=original.replace(/<!--POST-SHADOWAREA-->/,'<!--POST-SHADOWAREA-->\n<div id="vaultArea"></div>\n<!--POST-VAULTAREA-->');
var vaultStyles = '<!--PRE-VAULTSTYLE-START-->\n<style type="text/css">\n#vaultArea {display:none;}\n#vaultArea div {padding:0.5em; margin:1em 0em 0em 0em; border-color:#fff #666 #444 #ddd; border-style:solid; border-width:2px; overflow:auto;}\n</style>\n<!--PRE-VAULTSTYLE-END-->\n';
if (revised.search("<!--PRE-VAULTSTYLE-START-->")<0) var revised=revised.replace(/<!--POST-HEAD-START-->/,vaultStyles +'<!--POST-HEAD-START-->');
alert(config.messages.vaultCreationInfo);
return revised;
}
function locateVaultArea(original) //cloned from the TW2.2 standard function
{
// Locate the vaultArea div's. Should be just before the storeArea div
var posOpeningDiv = original.indexOf(startSaveVaultArea);
var limitClosingDiv = original.indexOf("<"+"!--POST-VAULTAREA--"+">");
if(limitClosingDiv == -1)
limitClosingDiv = original.indexOf("<div id="+'"storeArea"'+">");
var posClosingDiv = original.lastIndexOf(endSaveVaultArea,limitClosingDiv);
return (posOpeningDiv != -1 && posClosingDiv != -1) ? [posOpeningDiv,posClosingDiv] : null;
}
TiddlyWiki.prototype.allUnencryptedTiddlersAsHtml = function() {
return store.getSaver().externalize(store, SaverBase.systemStore);
};
TiddlyWiki.prototype.allEncryptedTiddlersAsHtml = function() {
return store.getSaver().externalize(store, SaverBase.vault);
};
SaverBase.prototype.externalize = function(store, tiddlerType) // overriding the TW2.2 standard function
{
var results = [];
var tiddlers = store.getTiddlers("title");
for(var t = 0; t < tiddlers.length; t++)
if (!tiddlerType || (this.getTiddlerType(tiddlers[t]) == tiddlerType)) // this line was changed from standard function
results.push(this.externalizeTiddler(store,tiddlers[t]));
return results.join("\n");
};
SaverBase.prototype.getTiddlerType= function(tiddler) {
if (tiddler.isTagged(SaverBase.vault)) return SaverBase.vault;
if (store.isShadowTiddler([tiddler.title])) return SaverBase.systemStore;
if (tiddler.isTagged("systemConfig")||tiddler.isTagged(SaverBase.systemStore)) return SaverBase.systemStore;
return SaverBase.vault;
};
LoaderBase.prototype.loadTiddler = function(store,node,tiddlers) // overriding the TW2.2 standard function
{
var title = this.getTitle(store,node);
if (store.getTiddler(title) && !confirm(config.messages.confirmOverload+"\n\n"+title)) // this line was changed from standard function
return;
if(title) {
var tiddler = store.createTiddler(title);
this.internalizeTiddler(store,tiddler,title,node);
tiddlers.push(tiddler);
}
};
window.saveChanges_noVault = window.saveChanges;
window.saveChanges= function(onlyIfDirty,tiddlers){
if (!vault.isLocked() || vault.purge || !vault.exists() || (vault.isLocked() && confirm(config.messages.saveWithLockedVaultConfirm)))
saveChanges_noVault(onlyIfDirty,tiddlers);
}
vault = {
load : function(){
if (!vault.isLocked()) {
alert(config.messages.vaultAlreadyUnlockedWarning);
return false;
}
else {
var storeElem = document.getElementById("vaultArea");
if (storeElem) {
var src = storeElem.innerHTML;
var pwd = vault.password ? vault.password : "";
while ((vault.isEncrypted(src)) && (pwd!=null)) {
if (pwd) src = vault.decrypt(src, pwd);
if (vault.isEncrypted(src)) pwd = prompt(vault.prompt,pwd);
}
if (pwd!=null) vault.password = pwd;
if (!vault.isEncrypted(src)) {
var wasDirty = store.isDirty();
var e = document.createElement("div");
e.innerHTML=src;
if (src) store.getLoader().loadTiddlers(store,e.childNodes);
vault.loaded = true;
refreshAll();
story.refreshAllTiddlers();
store.setDirty(wasDirty);
return true;
}
else return false;
}
}
},
decrypt : function(src,pwd){
var res = Crypto.cryptomx.decrypt(pwd,src.substr(vault.prefix.length));
return res ? res : src;
},
isEncrypted : function(src) {
return (src.substr(0,vault.prefix.length) == vault.prefix);
},
encrypt : function(src){
return vault.password ? vault.prefix + Crypto.cryptomx.encrypt(vault.password,src) : src;
},
isLocked : function(){
if (vault.loaded) return false;
var storeElem = document.getElementById("vaultArea");
return (!storeElem || (storeElem && vault.isEncrypted(storeElem.innerHTML)));
},
exists : function() {
return (document.getElementById("vaultArea")!=null);
},
prefix : "Cryptomx@",
prompt : "Enter a password",
loaded : false,
purge : false
}
config.macros.unlock = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var label = params[0] ? params[0] : "unlock vault";
var tooltip = params[1] ? params[1] : "unlock encrypted vault";
var openTiddlers = params[2] ? params[2] : "";
var closeTiddlers = params[3] ? params[3] : "";
if (vault.isLocked() && vault.exists()) {
var btn = createTiddlyButton(place,label, tooltip,this.onClick);
btn.setAttribute("openTiddlers",openTiddlers);
btn.setAttribute("closeTiddlers",closeTiddlers);
}
},
onClick:function(){
var openTiddlers = this.getAttribute("openTiddlers");
var closeTiddlers = this.getAttribute("closeTiddlers");
if (vault.load()) {
if (closeTiddlers) {
var tiddlers = store.filterTiddlers(closeTiddlers);
for(var t=0; t<tiddlers.length; t++) {
var elem = document.getElementById(story.idPrefix + tiddlers[t].title);
if (elem && elem.getAttribute("dirty")!="true")
story.closeTiddler(tiddlers[t].title);
}
}
if (openTiddlers) {
var tiddlers = store.filterTiddlers(openTiddlers);
for(var t=0; t<tiddlers.length; t++)
story.displayTiddler("bottom",tiddlers[t].title);
}
}
return false;
}
}
config.macros.setPassword = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var label = params[0] ? params[0] : "set password";
var tooltip = params[1] ? params[1] : "Set password for encrypted vault";
if (!vault.isLocked()) createTiddlyButton(place, label, tooltip,this.onClick);
},
onClick:function(){
var pwd = prompt(vault.prompt,(vault.password ? vault.password : ""));
if (pwd != null) vault.password = pwd;
return false;
}
}
config.macros.purge = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var label = params[0] ? params[0] : "purge vault";
var tooltip = params[1] ? params[1] : "Delete locked vault";
if (vault.isLocked() && vault.exists()) createTiddlyButton(place,label, tooltip,this.onClick);
},
onClick:function(){
if (!vault.isLocked())
alert(config.messages.noLockedVaultWarning);
else
if (confirm(config.messages.purgeConfirm)) {
vault.purge=true;
alert(config.messages.vaultPurgedInfo);
}
return false;
}
}
config.macros.ifLocked = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if (vault.isLocked() && vault.exists()) wikify(params[0],place,null,tiddler);
}
}
config.macros.ifUnlocked = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if (!vault.isLocked()) wikify(params[0],place,null,tiddler);
}
}
//}}}
/***
Cryptomx code from http://cryptomx.sourceforge.net
***/
//{{{
Crypto.cryptomx = {
dg :'',
makeArray: function(n) {
for (var i=1; i<=n; i++) {
this[i]=0
}
return this
},
rc4: function(key, text) {
var i, x, y, t, x2;
this.status("rc4")
s=this.makeArray(0);
for (i=0; i<256; i++) {
s[i]=i
}
y=0
for (x=0; x<256; x++) {
y=(key.charCodeAt(x % key.length) + s[x] + y) % 256
t=s[x]; s[x]=s[y]; s[y]=t
}
x=0; y=0;
var z=""
for (x=0; x<text.length; x++) {
x2=x % 256
y=( s[x2] + y) % 256
t=s[x2]; s[x2]=s[y]; s[y]=t
z+= String.fromCharCode((text.charCodeAt(x) ^ s[(s[x2] + s[y]) % 256]))
}
return z
},
badd: function(a,b) { // binary add
var r=''
var c=0
while(a || b) {
c=this.chop(a)+this.chop(b)+c
a=a.slice(0,-1); b=b.slice(0,-1)
if(c & 1) {
r="1"+r
} else {
r="0"+r
}
c>>=1
}
if(c) {r="1"+r}
return r
},
chop:function(a) {
if(a.length) {
return parseInt(a.charAt(a.length-1))
} else {
return 0
}
},
bsub:function(a,b) { // binary subtract
var r=''
var c=0
while(a) {
c=this.chop(a)-this.chop(b)-c
a=a.slice(0,-1); b=b.slice(0,-1)
if(c==0) {
r="0"+r
}
if(c == 1) {
r="1"+r
c=0
}
if(c == -1) {
r="1"+r
c=1
}
if(c==-2) {
r="0"+r
c=1
}
}
if(b || c) {return ''}
return this.bnorm(r)
},
bnorm:function(r) { // trim off leading 0s
var i=r.indexOf('1')
if(i == -1) {
return '0'
} else {
return r.substr(i)
}
},
bmul:function(a,b) { // binary multiply
var r=''; var p=''
while(a) {
if(this.chop(a) == '1') {
r=this.badd(r,b+p)
}
a=a.slice(0,-1)
p+='0'
}
return r;
},
bmod:function(a,m) { // binary modulo
return this.bdiv(a,m).mod
},
bdiv:function(a,m) { // binary divide & modulo
// this.q = quotient this.mod=remainder
var lm=m.length, al=a.length
var p='',d
this.q=''
for(n=0; n<al; n++) {
p=p+a.charAt(n);
if(p.length<lm || (d=this.bsub(p,m)) == '') {
this.q+='0'
} else {
if(this.q.charAt(0)=='0') {
this.q='1'
} else {
this.q+="1"
}
p=d
}
}
this.mod=this.bnorm(p)
return this
},
bmodexp:function(x,y,m) { // binary modular exponentiation
var r='1'
this.status("bmodexp "+x+" "+y+" "+m)
while(y) {
if(this.chop(y) == 1) {
r=this.bmod(this.bmul(r,x),m)
}
y=y.slice(0,y.length-1)
x=this.bmod(this.bmul(x,x),m)
}
return this.bnorm(r)
},
modexp:function(x,y,m) { // modular exponentiation
// convert packed bits (text) into strings of 0s and 1s
return this.b2t(this.bmodexp(this.t2b(x),this.t2b(y),this.t2b(m)))
},
i2b: function(i) { // convert integer to binary
var r=''
while(i) {
if(i & 1) { r="1"+r} else {r="0"+r}
i>>=1;
}
return r? r:'0'
},
t2b:function(s) {
var r=''
if(s=='') {return '0'}
while(s.length) {
var i=s.charCodeAt(0)
s=s.substr(1)
for(n=0; n<8; n++) {
r=((i & 1)? '1':'0') + r
i>>=1;
}
}
return this.bnorm(r)
},
b2t:function(b) {
var r=''; var v=0; var m=1
while(b.length) {
v|=this.chop(b)*m
b=b.slice(0,-1)
m<<=1
if(m==256 || b=='') {
r+=String.fromCharCode(v)
v=0; m=1
}
}
return r
},
b64s:'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"',
textToBase64:function(t) {
this.status("t 2 b64")
var r=''; var m=0; var a=0; var tl=t.length-1; var c
for(n=0; n<=tl; n++) {
c=t.charCodeAt(n)
r+=this.b64s.charAt((c << m | a) & 63)
a = c >> (6-m)
m+=2
if(m==6 || n==tl) {
r+=this.b64s.charAt(a)
if((n%45)==44) {r+="\n"}
m=0
a=0
}
}
return r
},
base64ToText:function(t) {
this.status("b64 2 t")
var r=''; var m=0; var a=0; var c
for(n=0; n<t.length; n++) {
c=this.b64s.indexOf(t.charAt(n))
if(c >= 0) {
if(m) {
r+=String.fromCharCode((c << (8-m))&255 | a)
}
a = c >> m
m+=2
if(m==8) { m=0 }
}
}
return r
},
rand:function(n) { return Math.floor(Math.random() * n) },
rstring:function(s,l) {
var r=""
var sl=s.length
while(l>0) {
l=l-1;
r+=s.charAt(rand(sl))
}
//status("rstring "+r)
return r
},
key2:function(k) {
var l=k.length
var kl=l
var r=''
while(l--) {
r+=k.charAt((l*3)%kl)
}
return r
},
rsaEncrypt:function(keylen,key,mod,text) {
// I read that rc4 with keys larger than 256 bytes doesn't significantly
// increase the level of rc4 encryption because it's sbuffer is 256 bytes
// makes sense to me, but what do i know...
this.status("encrypt")
if(text.length >= keylen) {
var sessionkey=this.rc4(rstring(text,keylen),rstring(text,keylen))
// session key must be less than mod, so mod it
sessionkey=this.b2t(bmod(t2b(sessionkey),t2b(mod)))
alert("sessionkey="+sessionkey)
// return the rsa encoded key and the encrypted text
// i'm double encrypting because it would seem to me to
// lessen known-plaintext attacks, but what do i know
return this.modexp(sessionkey,key,mod) +
this.rc4(this.key2(sessionkey),this.rc4(sessionkey,text))
} else {
// don't need a session key
return this.modexp(text,key,mod)
}
},
rsaDecrypt:function(keylen,key,mod,text) {
this.status("decrypt")
if(text.length <= keylen) {
return this.modexp(text,key,mod)
} else {
// sessionkey is first keylen bytes
var sessionkey=text.substr(0,keylen)
text=text.substr(keylen)
// un-rsa the session key
sessionkey=this.modexp(sessionkey,key,mod)
alert("sessionkey="+sessionkey)
// double decrypt the text
return this.rc4(sessionkey,this.rc4(this.key2(sessionkey,text),text))
}
},
trim2:function(d) { return d.substr(0,d.lastIndexOf('1')+1) },
bgcd:function(u,v) { // return greatest common divisor
// algorythm from http://algo.inria.fr/banderier/Seminar/Vallee/index.html
var d, t
while(1) {
d=this.bsub(v,u)
//alert(v+" - "+u+" = "+d)
if(d=='0') {return u}
if(d) {
if(d.substr(-1)=='0') {
v=d.substr(0,d.lastIndexOf('1')+1) // v=(v-u)/2^val2(v-u)
} else v=d
} else {
t=v; v=u; u=t // swap u and v
}
}
},
isPrime:function(p) {
var n,p1,p12,t
p1=this.bsub(p,'1')
t=p1.length-p1.lastIndexOf('1')
p12=this.trim2(p1)
for(n=0; n<2; n+=this.mrtest(p,p1,p12,t)) {
if(n<0) return 0
}
return 1
},
mrtest:function(p,p1,p12,t) {
// Miller-Rabin test from forum.swathmore.edu/dr.math/
var n,a,u
a='1'+this.rstring('01',Math.floor(p.length/2)) // random a
//alert("mrtest "+p+", "+p1+", "+a+"-"+p12)
u=this.bmodexp(a,p12,p)
if(u=='1') {return 1}
for(n=0;n<t;n++) {
u=this.bmod(this.bmul(u,u),p)
//dg+=u+" "
if(u=='1') return -100
if(u==p1) return 1
}
return -100
},
pfactors:'11100011001110101111000110001101',
// this number is 3*5*7*11*13*17*19*23*29*31*37
prime:function(bits) {
// return a prime number of bits length
var p='1'+this.rstring('001',bits-2)+'1'
while( ! this.isPrime(p)) {
p=badd(p,'10'); // add 2
}
alert("p is "+p)
return p
},
genkey:function(bits) {
q=prime(bits)
do {
p=q
q=prime(bits)
} while(bgcd(p,q)!='1')
p1q1=this.bmul(this.bsub(p,'1'),this.bsub(q,'1'))
// now we need a d, e, and an n so that:
// p1q1*n-1=de -> bmod(bsub(bmul(d,e),'1'),p1q1)='0'
// or more specifically an n so that d & p1q1 are rel prime and factor e
n='1'+this.rstring('001',Math.floor(bits/3)+2)
alert('n is '+n)
factorMe=this.badd(this.bmul(p1q1,n),'1')
alert('factor is '+factorMe)
//e=bgcd(factorMe,p1q1)
//alert('bgcd='+e)
e='1'
// is this always 1?
//r=bdiv(factorMe,e)
//alert('r='+r.q+" "+r.mod)
//if(r.mod != '0') {alert('Mod Error!')}
//factorMe=r.q
d=this.bgcd(factorMe,'11100011001110101111000110001101')
alert('d='+d)
if(d == '1' && e == '1') {alert('Factoring failed '+factorMe+' p='+p+' q='+q)}
e=this.bmul(e,d)
r=this.bdiv(factorMe,d)
d=r.q
if(r.mod != '0') {alert('Mod Error 2!')}
this.mod=this.b2t(bmul(p,q))
this.pub=this.b2t(e)
this.priv=this.b2t(d)
},
status:function(a) { },//alert(a)}
encrypt:function(key,text) {
return this.textToBase64(this.rc4(key,"check:"+text));
},
decrypt:function(key,text){
var uncrypt = this.rc4(key,this.base64ToText(text));
return (uncrypt.substr(0,6)=="check:") ? uncrypt.substr(6) : null;
}
}
//}}}
[[EncryptedVaultPlugin]] demo is available [[here|http://visualtw.ouvaton.org/demo/EncryptedVaultPlugin.html]].
/***
|''Name:''|ExternalizePlugin|
|''Description:''|Edit tiddlers directly with your favorite external editor (html editor, text processor, javascript IDE, css editor, ...).|
|''Version:''|1.0.1|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0|
!Installation
#install [[it's All Text!|https://addons.mozilla.org/fr/firefox/addon/4125]] Firefox extension.
#set up [[it's All Text!|https://addons.mozilla.org/fr/firefox/addon/4125]] options in its dialog box (see tips below).
#import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig).
#save and reload.
#set up hotkey below.
#use the <<toolbar externalize>> button in the tiddler's toolbar (in default ViewTemplate) or add {{{externalize}}} command in your own toolbar.
! Useful Addons
*[[HTMLFormattingPlugin|http://www.tiddlytools.com/#HTMLFormattingPlugin]] to embed wiki syntax in html tiddlers.<<br>>//__Tips__ : When this plugin is installed, you can use anchor syntax to link tiddlers in wysiwyg mode (example : #example). Anchors are converted back and from wiki syntax when editing.//
*[[TaggedTemplateTweak|http://www.TiddlyTools.com/#TaggedTemplateTweak]] to use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values.
!Configuration options
|[[it's All Text!|https://addons.mozilla.org/fr/firefox/addon/4125]] extension hotkey (copy/paste from the extension dialog box)|<<option txtExternalizeHotkey>>|
|Optional tiddler containing instructions to process the text before and after externalization<<br>>Example : [[ExternalizeAsHTML]]|<<option txtExternalizeProccessing>>|
|Template called by the {{{externalize}}} button|[[ExternalizeTemplate]]|
|Max waiting time for //It's All text!// to fire|<<option txtExternalizeMaxTime>>|
!//It's all text!// extension tips
*Tiddler text is edited with the first file extension
*Copy/paste Hot Key from the dialog box (with context menu)
*Edit button isn't necessary for the plugin (it uses hotkey)
*Try the extension configuration first, before trying it with the plugin.
!Code
***/
//{{{
config.options.txtExternalizeHotkey = config.options.txtExternalizeHotkey ? config.options.txtExternalizeHotkey : "";
config.options.txtExternalizeProccessing = config.options.txtExternalizeProccessing ? config.options.txtExternalizeProccessing : "";
config.options.txtExternalizeMaxTime = config.options.txtExternalizeMaxTime ? config.options.txtExternalizeMaxTime : "30";
config.macros.externalize = {
noExtensionError : "It's all text ! extension wasn't available. Try to fire it manually with htokey or button. If it works, adapt your configuration (increase max waiting time or change hotkey) and try again.",
hotKeyError : "Hotkey wasn't understood. Use copy/paste from it's all text set up dialog.",
EmptyHotKeyError : "Hotkey isn't defined. Check ExternalizePlugin configuration.",
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var field = params[0];
var rows = params[1] || 0;
var defVal = params[2] || '';
if((tiddler instanceof Tiddler) && field) {
story.setDirty(tiddler.title,true);
var e,v;
var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
var wrapper2 = createTiddlyElement(wrapper1,"div");
e = createTiddlyElement(wrapper2,"textarea");
e.setAttribute("readOnly","readOnly");
v = config.macros.externalize.getValue(tiddler,field);
v = v ? v : defVal;
e.value = v;
rows = rows ? rows : 10;
var lines = v.match(/\n/mg);
var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
if(lines != null && lines.length > rows)
rows = lines.length + 5;
rows = Math.min(rows,maxLines);
var id=tiddler.title+"externalize"+field;
e.setAttribute("id",id);
e.setAttribute("rows",rows);
e.setAttribute("externalize",field);
place.appendChild(wrapper1);
config.macros.externalize.externalEdit(id);
return e;
}
},
externalEdit : function(id){
window.setTimeout(function(){
var element = document.getElementById(id);
if (element) {
var cpt=element.getAttribute("cpt");
cpt = cpt ? cpt -1 : parseInt(config.options.txtExternalizeMaxTime);
element.setAttribute("cpt",cpt);
if (cpt>0) {
if (element.getAttribute("itsalltext_uid")) {
element.dispatchEvent(config.macros.externalize.getKeyEvent());
addClass(element,"externalized");
}
else window.setTimeout(arguments.callee,100)
}
else alert(config.macros.externalize.noExtensionError);
}
},1000)
},
getKeyEvent : function(){
var hotkey = config.options.txtExternalizeHotkey;
if (hotkey) {
var m = hotkey.match(/^(alt)?\s*(ctrl)?\s*(meta)?\s*(shift)?\s*(\w+)\s*$/i);
if (m) {
var ev = document.createEvent("KeyboardEvent");
var cc = m[4]!=undefined ? m[5].toUpperCase() : m[5].toLowerCase();
var charCode = m[5].length==1 ? cc.charCodeAt(0) : 0;
var keyCode = m[5].length>1 ? config.macros.externalize.keyMap[m[5]] : 0;
ev.initKeyEvent("keypress",true,true,window,m[2]!=undefined,m[1]!=undefined,m[4]!=undefined,m[3]!=undefined,keyCode,charCode);
return ev;
}
else alert(config.macros.externalize.hotKeyError);
}
else alert(config.macros.externalize.EmptyHotKeyError);
},
getValue : function(tiddler,field){
var v = store.getValue(tiddler,field);
v = v ? config.macros.externalize.textProcessing(v, "Before") : "";
v = v.replace(/\[\[([^|\]]*)\|([^\]]*)]]/g,'<a href="#$2">$1</a>');
return v;
},
gather : function(e){
return config.macros.externalize.textProcessing(e.value,"After");
},
readParam : function(source,param){
var re = new RegExp("^"+ param +"\\s*: *(.*)$","mg");
var r = source && re ? re.exec(source) : null;
return r!=null ? r[1] : null;
},
textProcessing : function(text,key) {
var params = config.options.txtExternalizeProccessing;
var rexp = "^\\["+key+"\\] *(.*)\n(.*)\\n(.*)$";
if (params) {
var source = store.getTiddler(params);
source = source ? source.text : config.shadowTiddlers[params];
if (source) {
var re=new RegExp(rexp,"mg");
var instructions = source.match(re);
for(var cpt=0; cpt<instructions.length; cpt++){
re=new RegExp(rexp,"mg");
var res = re.exec(instructions[cpt]);
text = text.replace(new RegExp(res[2],res[1]),res[3]);
}
}
}
return text;
}
}
config.commands.externalize= {
text: "externalize",
tooltip: "Edit this tiddler with an external editor",
handler : function(event,src,title) {
clearMessage();
var tiddlerElem = document.getElementById(story.idPrefix + title);
var fields = tiddlerElem.getAttribute("tiddlyFields");
story.displayTiddler(null,title,"ExternalizeTemplate",false,null,fields);
story.focusTiddler(title,"text");
return false;
}
}
Story.prototype.previousGatherSaveExternalize = Story.prototype.previousGatherSaveExternalize ? Story.prototype.previousGatherSaveExternalize : Story.prototype.gatherSaveFields; // to avoid looping if this line is called several times
Story.prototype.gatherSaveFields = function(e,fields){
if(e && e.getAttribute) {
var f = e.getAttribute("externalize");
if(f){
var newVal = config.macros.externalize.gather(e);
if (newVal) fields[f] = newVal;
}
this.previousGatherSaveExternalize(e, fields);
}
}
config.macros.externalize.keyMap = {
'Backspace' : 8,
'Tab' : 9,
'Enter' : 13,
'Break' : 19,
'Escape' : 27,
'PgUp' : 33,
'PgDn' : 34,
'End' : 35,
'Home' : 36,
'Left' : 37,
'Up' : 38,
'Right' : 39,
'Down' : 40,
'Insert' : 45,
'Delete' : 46,
'F1' : 112,
'F2' : 113,
'F3' : 114,
'F4' : 115,
'F5' : 116,
'F6' : 117,
'F7' : 118,
'F8' : 119,
'F9' : 120,
'F10' : 121,
'F11' : 122,
'Num Lock' : 144,
'Scroll Lock' : 145
};
config.shadowTiddlers.ExternalizeAsHTML = "/*{{{*/\n";
config.shadowTiddlers.ExternalizeAsHTML += "[Before] g\n\\n\n<br/>\n\n";
config.shadowTiddlers.ExternalizeAsHTML += "[Before] gi\n(?:^<html>(.*)<\/html>$)|(^.*$)\n<html><body>$1$2</body></html>\n\n";
config.shadowTiddlers.ExternalizeAsHTML += "[After] g\n\\n|\\t\n\n\n";
config.shadowTiddlers.ExternalizeAsHTML += "[After] gi\n.*<html[^>]*>.*<body[^>]*>(.*)<\/body><\/html>\n<html>$1</html>\n\n";
config.shadowTiddlers.ExternalizeAsHTML += "/*}}}*/\n";
config.shadowTiddlers.ViewTemplate = config.shadowTiddlers.ViewTemplate.replace(/\+editTiddler/,"+editTiddler externalize");
config.shadowTiddlers.ExternalizeTemplate = config.shadowTiddlers.EditTemplate.replace(/macro='edit text'/,"macro='externalize text'");
config.shadowTiddlers.StyleSheetExternalize = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetExternalize += ".externalized {color: [[ColorPalette::TertiaryMid]]}\n";
config.shadowTiddlers.StyleSheetExternalize +="/*}}}*/";
store.addNotification("StyleSheetExternalize", refreshStyles);
//}}}
Renamed FieldsEditorPlugin
/***
|''Name:''|FieldsEditorPlugin|
|''Description:''|//create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.|
|''Version:''|1.0.2|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demo:
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], see [[FieldEditor example]]
!Installation:
*import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
*save and reload
*optionnaly : add the following css text in your StyleSheet : {{{#popup tr.fieldTableRow td {padding:1px 3px 1px 3px;}}}}
!Code
***/
//{{{
config.commands.fields.handlePopup = function(popup,title) {
var tiddler = store.fetchTiddler(title);
if(!tiddler)
return;
var fields = {};
store.forEachField(tiddler,function(tiddler,fieldName,value) {fields[fieldName] = value;},true);
var items = [];
for(var t in fields) {
var editCommand = "<<untiddledCall editFieldDialog "+escape(title)+" "+escape(t)+">>";
var deleteCommand = "<<untiddledCall deleteField "+escape(title)+" "+escape(t)+">>";
var renameCommand = "<<untiddledCall renameField "+escape(title)+" "+escape(t)+">>";
items.push({field: t,value: fields[t], actions: editCommand+renameCommand+deleteCommand});
}
items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
var createNewCommand = "<<untiddledCall createField "+escape(title)+">>";
items.push({field : "", value : "", actions:createNewCommand });
if(items.length > 0)
ListView.create(popup,items,this.listViewTemplate);
else
createTiddlyElement(popup,"div",null,null,this.emptyText);
}
config.commands.fields.listViewTemplate = {
columns: [
{name: 'Field', field: 'field', title: "Field", type: 'String'},
{name: 'Actions', field: 'actions', title: "Actions", type: 'WikiText'},
{name: 'Value', field: 'value', title: "Value", type: 'WikiText'}
],
rowClasses: [
{className: 'fieldTableRow', field: 'actions'}
],
buttons: [ //can't use button for selected then delete, because click on checkbox will hide the popup
]
}
config.macros.untiddledCall = { // when called from listview, tiddler is unset, so we need to pass tiddler as parameter
handler : function(place,macroName,params,wikifier,paramString) {
var macroName = params.shift();
if (macroName) var macro = config.macros[macroName];
var title = params.shift();
if (title) var tiddler = store.getTiddler(unescape(title));
if (macro) macro.handler(place,macroName,params,wikifier,paramString,tiddler);
}
}
config.macros.deleteField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"delete", "delete "+fieldName,this.onClickDeleteField);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickDeleteField : function() {
var title=this.getAttribute("title");
var fieldName=this.getAttribute("fieldName");
var tiddler = store.getTiddler(title);
if (tiddler && fieldName && confirm("delete field " + fieldName+" from " + title +" tiddler ?")) {
delete tiddler.fields[fieldName];
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
return false;
}
}
config.macros.createField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly) {
var btn = createTiddlyButton(place,"create new", "create a new field",this.onClickCreateField);
btn.setAttribute("title",tiddler.title);
}
},
onClickCreateField : function() {
var title=this.getAttribute("title");
var tiddler = store.getTiddler(title);
if (tiddler) {
var fieldName = prompt("Field name","");
if (store.getValue(tiddler,fieldName)) {
window.alert("This field already exists.");
}
else if (fieldName) {
var v = prompt("Field value","");
tiddler.fields[fieldName]=v;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.macros.editFieldDialog = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"edit", "edit this field",this.onClickEditFieldDialog);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickEditFieldDialog : function() {
var title=this.getAttribute("title");
var tiddler = store.getTiddler(title);
var fieldName=this.getAttribute("fieldName");
if (tiddler && fieldName) {
var value = tiddler.fields[fieldName];
value = value ? value : "";
var lines = value.match(/\n/mg);
lines = lines ? true : false;
if (!lines || confirm("This field contains more than one line. Only the first line will be kept if you edit it here. Proceed ?")) {
var v = prompt("Field value",value);
tiddler.fields[fieldName]=v;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.macros.renameField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"rename", "rename "+fieldName,this.onClickRenameField);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickRenameField : function() {
var title=this.getAttribute("title");
var fieldName=this.getAttribute("fieldName");
var tiddler = store.getTiddler(title);
if (tiddler && fieldName) {
var newName = prompt("Rename " + fieldName + " as ?", fieldName);
if (newName) {
tiddler.fields[newName]=tiddler.fields[fieldName];
delete tiddler.fields[fieldName];
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.shadowTiddlers.StyleSheetFieldsEditor = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow td {padding : 1px 3px}\n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow .button {border:0; padding : 0 0.2em}\n";
config.shadowTiddlers.StyleSheetFieldsEditor +="/*}}}*/";
store.addNotification("StyleSheetFieldsEditor", refreshStyles);
//}}}
/***
|Name|FontSizePlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#FontSizePlugin|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Resize tiddler text on the fly. The text size is remembered between sessions by use of a cookie.
You can customize the maximum and minimum allowed sizes.
(only affects tiddler content text, not any other text)
Also, you can load a TW file with a font-size specified in the url.
Eg: http://tw.lewcid.org/#font:110
!Demo:
Try using the font-size buttons in the sidebar, or in the MainMenu above.
!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Then put {{{<<fontSize "font-size:">>}}} in your SideBarOptions tiddler, or anywhere else that you might like.
!Usage
{{{<<fontSize>>}}} results in <<fontSize>>
{{{<<fontSize font-size: >>}}} results in <<fontSize font-size:>>
!Customizing:
The buttons and prefix text are wrapped in a span with class fontResizer, for easy css styling.
To change the default font-size, and the maximum and minimum font-size allowed, edit the config.fontSize.settings section of the code below.
!Notes:
This plugin assumes that the initial font-size is 100% and then increases or decreases the size by 10%. This stepsize of 10% can also be customized.
!History:
*27-07-06, version 1.0 : prevented double clicks from triggering editing of containing tiddler.
*25-07-06, version 0.9
!Code
***/
//{{{
config.fontSize={};
//configuration settings
config.fontSize.settings =
{
defaultSize : 100, // all sizes in %
maxSize : 200,
minSize : 40,
stepSize : 10
};
//startup code
var fontSettings = config.fontSize.settings;
if (!config.options.txtFontSize)
{config.options.txtFontSize = fontSettings.defaultSize;
saveOptionCookie("txtFontSize");}
setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
setStylesheet("#contentWrapper .fontResizer .button {display:inline;font-size:105%; font-weight:bold; margin:0 1px; padding: 0 3px; text-align:center !important;}\n .fontResizer {margin:0 0.5em;}","fontResizerButtonStyles");
//macro
config.macros.fontSize={};
config.macros.fontSize.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
var sp = createTiddlyElement(place,"span",null,"fontResizer");
sp.ondblclick=this.onDblClick;
if (params[0])
createTiddlyText(sp,params[0]);
createTiddlyButton(sp,"+","increase font-size",this.incFont);
createTiddlyButton(sp,"=","reset font-size",this.resetFont);
createTiddlyButton(sp,"–","decrease font-size",this.decFont);
}
config.macros.fontSize.onDblClick = function (e)
{
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return false;
}
config.macros.fontSize.setFont = function ()
{
saveOptionCookie("txtFontSize");
setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
}
config.macros.fontSize.incFont=function()
{
if (config.options.txtFontSize < fontSettings.maxSize)
config.options.txtFontSize = (config.options.txtFontSize*1)+fontSettings.stepSize;
config.macros.fontSize.setFont();
}
config.macros.fontSize.decFont=function()
{
if (config.options.txtFontSize > fontSettings.minSize)
config.options.txtFontSize = (config.options.txtFontSize*1) - fontSettings.stepSize;
config.macros.fontSize.setFont();
}
config.macros.fontSize.resetFont=function()
{
config.options.txtFontSize=fontSettings.defaultSize;
config.macros.fontSize.setFont();
}
config.paramifiers.font =
{
onstart: function(v)
{
config.options.txtFontSize = v;
config.macros.fontSize.setFont();
}
};
//}}}
FontSizePlugin has been updated to prevent double clicks of the button from triggering editing of the containing tiddler.
''Creating a footnote is very easy. Just put the text of the footnote inside triple backticks.''
{{{``` text of footnote ```}}}
''Try clicking on the red numbers, in the paragraphs below, to see the footnotes.
Edit this tiddler, to see how easy it is, to create footnotes.''
Lorem ipsum dolor sit amet, consectetuer adipiscing elit```This is my first footnote```. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
Ut elementum egestas nibh. Sed at urna non lectus```You can have as many footnotes as you like``` accumsan lobortis. Ut risus nibh, commodo non, blandit sit amet, consequat id, nisl. Nulla facilisi. Curabitur massa magna, vulputate sed, porttitor accumsan, eleifend sit amet, dui. Curabitur risus. Integer id enim vel ligula porttitor laoreet. Vivamus congue lorem id urna. Donec viverra. Donec et massa non arcu sollicitudin bibendum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque velit mauris, lacinia eget, lobortis vitae, aliquam a, lectus. Donec pulvinar, libero sit amet auctor volutpat, mauris est posuere nisi, vel aliquet enim nisi in ipsum. Nullam at eros ac leo convallis blandit```Clicking on a footnote link, takes you to the footnote```.
Aliquam erat volutpat. Nam congue. Maecenas vitae tortor. In enim leo, rutrum non, tincidunt at, adipiscing in, lectus. Donec bibendum, lacus a ultricies ultricies, lacus erat rhoncus augue, sit amet vehicula libero massa eget sem. Donec quis felis. Nullam auctor interdum purus. Mauris mauris. Integer interdum blandit erat. Nulla facilisi. Integer fermentum gravida nunc. Maecenas vitae justo ut tortor ultrices dictum. Maecenas purus magna, pellentesque vel, luctus vel, commodo a, enim. Ut convallis, metus in consectetuer dapibus, nisi mi malesuada justo, nec feugiat leo magna et orci. In hendrerit enim eget sem sollicitudin auctor```Footnotes are numbered automatically```. Donec hendrerit, lorem id tincidunt bibendum, dolor dui dignissim velit, eu aliquet dolor sapien tincidunt nunc. Duis condimentum leo laoreet nibh. Proin in lacus quis ante lacinia vestibulum.
Donec pharetra diam at massa. Aliquam ut eros in odio malesuada euismod. Nam interdum. Sed quis quam sed justo hendrerit facilisis. Morbi euismod. Fusce urna lacus, lobortis vitae, feugiat quis, commodo eu, dui. Nunc dui lacus, ultricies sed, pharetra ac, feugiat id, velit. Sed accumsan, metus at pharetra accumsan, nisl ante vulputate lectus, in pretium dui sem nec dui. Quisque mattis arcu eget nulla. Mauris turpis. Donec elementum lacinia turpis. Donec enim diam, feugiat id, feugiat gravida, mollis non, magna```Each footnote, has a back button, to take you to where you came from```.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit This is my first footnote. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit This is my first footnote. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit This is my first footnote. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit This is my first footnote. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit This is my first footnote. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit This is my first footnote. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit This is my first footnote. Duis eleifend. Phasellus id orci. Suspendisse quis elit pharetra arcu fringilla vulputate. Nullam et orci. In vel dolor quis eros euismod vehicula. Mauris eros lectus, imperdiet id, aliquet quis, mollis bibendum, libero. Suspendisse turpis diam, lobortis id, consectetuer a, porta a, nisl. Morbi tristique, tellus ac mollis suscipit, dolor dui convallis massa, a tristique ligula nisl ac turpis. Pellentesque in elit sit amet urna mattis vulputate. Cras convallis gravida nulla. Integer luctus ante et velit. In vel urna. Donec in sapien.
''Martin Jirsak MAJ'' - I'm film, scenic, thatre and dramatic music composer.
[[This is my music|Music]].
Motto: Music is one of the best tool for evoke the atmosphere.
/***
|Name|GotoPlugin|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Version|1.4.3|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|view any tiddler by entering it's title - displays list of possible matches|
''View a tiddler by typing its title and pressing //enter//.'' Input just enough to uniquely match a single tiddler title and ''press //enter// to auto-complete the title for you!!'' If multiple titles match your input, a list is displayed. You can scroll-and-click (or use arrows+enter) to select/view a tiddler, or press //escape// to close the listbox to resume typing. When the listbox is ''//not//'' being displayed, press //escape// to clear the current text input and start over.
Note: ''At any time, you can move the focus directly to the text input field by using the ~ALT-G keyboard shortcut.''
!!!!!Examples
<<<
| //IMPORTANT NOTE:// ''As of version 1.4.0 (2007.04.25),<br>to avoid conflict with javascript reserved keywords<br>the {{{<<goto>>}}} macro has been renamed to {{{<<gotoTiddler>>}}}'' |
syntax: {{{<<gotoTiddler quiet insert inputstyle liststyle>>}}}
All parameters are optional.
* ''quiet'' prevents //automatic// display of the list as each character is typed. To view the list when ''quiet'', use //down// or //enter//.
* ''insert'' causes the selected tiddler title to be inserted into the tiddler source currently being edited (use with EditTemplate)
* ''inputstyle'' and ''liststyle'' are CSS declarations that modify the default input and listbox styles. Note: styles containing spaces must be surrounded by ({{{"..."}}} or {{{'...'}}}) or ({{{[[...]]}}}).
{{{<<gotoTiddler>>}}}
<<gotoTiddler>>
{{{<<gotoTiddler quiet>>}}}
<<gotoTiddler quiet>>
{{{<<goto width:20em width:20em>>}}}
<<gotoTiddler width:20em width:20em>>
You can also invoke the macro with the "insert" keyword. When used in the [[EditTemplate]], like this:
{{{
<span macro="gotoTiddler insert"></span>
}}}
it allows you to type/select a tiddler title, and instantly insert a link to that title (e.g. {{{[[TiddlerName]]}}}) into the tiddler source being edited.
<<<
!!!!!Configuration
<<<
You can create a tiddler tagged with <<tag systemConfig>> to control the maximum height of the listbox of tiddlers/shadows/tags. //The default values are shown below://
//{{{
config.macros.gotoTiddler.listMaxSize=10;
//}}}
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''GotoPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revisions
<<<
''2007.10.31 [1.4.3]'' removed extra trailing comma on last property of config.macros.gotoTiddler object. This fixes an error under InternetExplorer that was introduced 6 days ago... sure, I should have found it sooner, but... ''WHY DON'T PEOPLE TELL ME WHEN THINGS ARE BROKEN!!!!''
''2007.10.25 [1.4.2]'' added onclick handler for input field, so that clicking in field hides the listbox.
''2007.10.25 [1.4.1]'' re-wrote getItems() to cache list of tiddlers/shadows/tags and use case-folded simple text match instead of regular expression to find matching tiddlers. This *vastly* reduces processing overhead between keystrokes, especially for documents with many (>1000) tiddlers. Also, removed local definition of replaceSelection(), now supported directly by the TW2.2+ core, as well as via backward-compatible plugin (see [[CoreTweaksArchive]]).
''2007.04.25 [1.4.0]'' renamed macro from "goto" to "gotoTiddler". This was necessary to avoid a fatal syntax error in Opera (and other browsers) that require strict adherence to ECMAScript 1.5 standards which defines the identifier "goto" as "reserved for FUTURE USE"... *sigh*
''2007.04.21 [1.3.2]'' in html definition, removed DIV around droplist (see 1.2.6 below). It created more layout problems then it solved. :-(
''2007.04.01 [1.3.1]'' in processItem(), ensure that correct textarea field is found by checking for edit=="text" attribute
''2007.03.30 [1.3.0]'' tweak SideBarOptions shadow to automatically add {{{<<goto>>}}} when using default sidebar content
''2007.03.30 [1.2.6]'' in html definition, added DIV around droplist to fix IE problem where list appears next to input field instead of below it.
''2007.03.28 [1.2.5]'' in processItem(), set focus to text area before setting selection (needed for IE to get correct selection 'range')
''2007.03.28 [1.2.4]'' added prompt for 'pretty text' when inserting a link into tiddler content
''2007.03.28 [1.2.3]'' added local copy of core replaceSelection() and modified for different replace logic
''2007.03.27 [1.2.2]'' in processItem(), use story.getTiddlerField() to retrieve textarea control
''2007.03.26 [1.2.1]'' in html, use either 'onkeydown' (IE) or 'onkeypress' (Moz) event to process <esc> key sooner, to prevent <esc> from 'bubbling up' to the tiddler (which will close the current editor).
''2007.03.26 [1.2.0]'' added support for optional "insert" keyword param. When used in [[EditTemplate]], (e.g. {{{<span macro="goto insert"></span>}}}) it triggers alternative processing: instead of displaying the selected tiddler, that tiddler's title is inserted into a tiddler's textarea edit field surrounded by {{{[[...]]}}}.
''2006.05.10 [1.1.2]'' when filling listbox, set selection to 'heading' item... auto-select first tiddler title when down/enter moves focus into listbox
''2006.05.08 [1.1.1]'' added accesskey ("G") to input field html (also set when field gets focus). Also, inputKeyHandler() skips non-printing/non-editing keys.
''2006.05.08 [1.1.0]'' added heading to listbox for better feedback (also avoids problems with 1-line droplist)
''2006.05.07 [1.0.0]'' list matches against tiddlers/shadows/tags. input field auto-completion... 1st enter=complete matching input (or show list)... 2nd enter=view tiddler. optional "quiet" param controls when listbox appears.
''2006.05.06 [0.5.0]'' added handling for enter (13), escape(27), and down(40) keys. Change 'ondblclick' to 'onclick' for list handler to view tiddlers (suggested by Florian Cauvin - prevents unintended trigger of tiddler editor). shadow titles inserted into list instead of appended to the end.
''2006.05.05 [0.0.0]'' started
<<<
!!!!!Credits
>This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
!!!!!Code
***/
//{{{
version.extensions.gotoTiddler = {major: 1, minor: 4, revision: 3, date: new Date(2007,10,31)};
// automatically tweak shadow SideBarOptions to add <<gotoTiddler>> macro above <<search>>
config.shadowTiddlers.SideBarOptions=config.shadowTiddlers.SideBarOptions.replace(/<<search>>/,"{{button{goto}}}\n<<gotoTiddler>><<search>>");
config.macros.gotoTiddler= {
handler:
function(place,macroName,params) {
var quiet=(params[0] && params[0]=="quiet"); if (quiet) params.shift();
var insert=(params[0] && params[0]=="insert"); if (insert) params.shift();
var instyle=params.shift(); if (!instyle) instyle="";
var liststyle=params.shift(); if (!liststyle) liststyle="";
var keyevent=window.event?"onkeydown":"onkeypress";
createTiddlyElement(place,"span").innerHTML
=this.html.replace(/%keyevent%/g,keyevent).replace(/%insert%/g,insert).replace(/%quiet%/g,quiet).replace(/%instyle%/g,instyle).replace(/%liststyle%/g,liststyle);
},
html:
'<form onsubmit="return false" style="display:inline;margin:0;padding:0">\
<input name=gotoTiddler type=text autocomplete="off" accesskey="G" style="%instyle%"\
title="enter a tiddler title"\
onclick="this.form.list.style.display=\'none\';"\
onfocus="this.select(); this.setAttribute(\'accesskey\',\'G\');"\
%keyevent%="return config.macros.gotoTiddler.inputEscKeyHandler(event,this,this.form.list);"\
onkeyup="return config.macros.gotoTiddler.inputKeyHandler(event,this,this.form.list,%quiet%,%insert%);">\
<select name=list style="%liststyle%;display:none;position:absolute"\
onchange="if (!this.selectedIndex) this.selectedIndex=1;"\
onblur="this.style.display=\'none\';"\
%keyevent%="return config.macros.gotoTiddler.selectKeyHandler(event,this,this.form.gotoTiddler,%insert%);"\
onclick="return config.macros.gotoTiddler.processItem(this.value,this.form.gotoTiddler,this,%insert%);">\
</select>\
</form>',
getItems:
function(val) {
if (!this.items.length || val.length<2) { // starting new search, refresh cached list of tiddlers/shadows/tags
this.items=new Array();
var tiddlers=store.getTiddlers("title","excludeLists");
for(var t=0; t<tiddlers.length; t++) this.items.push(tiddlers[t].title);
for (var t in config.shadowTiddlers) this.items.pushUnique(t);
var tags=store.getTags();
for(var t=0; t<tags.length; t++) this.items.pushUnique(tags[t][0]);
}
var found = [];
var match=val.toLowerCase();
for(var i=0; i<this.items.length; i++)
if (this.items[i].toLowerCase().indexOf(match)!=-1) found.push(this.items[i]);
return found;
},
items: [], // cached list of tiddlers/shadows/tags
getItemSuffix:
function(t) {
if (store.tiddlerExists(t)) return ""; // tiddler
if (store.isShadowTiddler(t)) return " (shadow)"; // shadow
return " (tag)"; // tag
},
keyProcessed:
function(ev) { // utility function: exits handler and prevents browser from processing the keystroke
ev.cancelBubble=true; // IE4+
try{event.keyCode=0;}catch(e){}; // IE5
if (window.event) ev.returnValue=false; // IE6
if (ev.preventDefault) ev.preventDefault(); // moz/opera/konqueror
if (ev.stopPropagation) ev.stopPropagation(); // all
return false;
},
inputEscKeyHandler:
function(event,here,list) {
var key=event.keyCode;
// escape... hide list (2nd esc=clears input)
if (key==27) {
if (list.style.display=="none")
here.value=here.defaultValue;
list.style.display="none";
return this.keyProcessed(event);
}
return true; // key bubbles up
},
inputKeyHandler:
function(event,here,list,quiet,insert) {
var key=event.keyCode;
// non-printing chars... bubble up, except: backspace=8, enter=13, space=32, down=40, delete=46
if (key<48) switch(key) { case 8: case 13: case 32: case 40: case 46: break; default: return true; }
// blank input... if down/enter... fall through (list all)... else, and hide list
if (!here.value.length && !(key==40 || key==13))
{ list.style.display="none"; return this.keyProcessed(event); }
// find matching items...
var found = this.getItems(here.value);
// matched one item using enter key, but not an *exact* match... autocomplete input field
if (found.length==1 && quiet && key==13 && here.value!=found[0])
{ list.style.display="none"; here.value=found[0]; return this.keyProcessed(event); }
// no match or exact match using enter key, create/show tiddler
if (found.length<2 && key==13)
return this.processItem(found.length?found[0]:here.value,here,list,insert);
// quiet/no match, make sure list is hidden
list.style.display=(!quiet && found.length)?"block":"none";
// no matches, key bubbles up
if (!found.length) return true;
// using down/enter key shows/moves to list...
if (key==40 || key==13) { list.style.display="block"; list.focus(); }
// finally, if list is showing, fill it with found results...
if (list.style.display!="none") {
while (list.length > 0) list.options[0]=null; // clear list
found.sort(); // alpha by title
var hdr=found.length==1?this.listMatchMsg:this.listHeading.format([found.length]); // list 'heading'
list.options[0]=new Option(hdr,"",false,false);
for (var t=0; t<found.length; t++) // fill list...
list.options[list.length]=new Option(found[t]+this.getItemSuffix(found[t]),found[t],false,false);
list.size=(found.length<this.listMaxSize?found.length:this.listMaxSize)+1; // resize list...
list.selectedIndex=(key==40 || key==13)?1:0;
}
return true; // key bubbles up
},
listMaxSize: 10,
listHeading: 'Found %0 matching titles:',
listMatchMsg: 'Press enter to open tiddler...',
selectKeyHandler:
function(event,list,editfield,insert) {
if (event.keyCode==27) // escape... hide list, move to edit field
{ editfield.focus(); list.style.display="none"; return this.keyProcessed(event); }
if (event.keyCode==13 && list.value.length) // enter... view selected item
{ this.processItem(list.value,editfield,list,insert); return this.keyProcessed(event); }
return true; // key bubbles up
},
processItem:
function(title,here,list,insert) {
if (!title.length) return; here.value=title; list.style.display='none';
if (insert) {
var tidElem=story.findContainingTiddler(here); if (!tidElem) { here.focus(); return false; }
var e=story.getTiddlerField(tidElem.getAttribute("tiddler"),"text");
if (!e||e.getAttribute("edit")!="text") return false;
var txt=prompt(this.askForText,title); if (!txt||!txt.length) { here.focus(); return false; }
e.focus(); // put focus on target field before setting selection
replaceSelection(e,"[["+txt+"|"+title+"]]"); // insert selected tiddler as a PrettyLink
}
else
story.displayTiddler(null,title); // show selected tiddler
return false;
},
askForText: "Enter the text to display for this link"
}
//}}}
/***
|Name|HTMLFormattingPlugin|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Version|2.1.5|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|'HTML' formatter|
|Description|embed wiki syntax formatting inside of HTML content|
The shorthand Wiki-style formatting syntax of ~TiddlyWiki is very convenient and enables most content to be reasonably well presented. However, there are times when tried-and-true HTML formatting syntax allows more more precise control of the content display.
When HTML formatting syntax is embedded within a tiddler (in between {{{<}}}{{{html>}}} and {{{<}}}{{{/html>}}} markers) TiddlyWiki passes this content to the browser for processing as 'native' HTML. However, TiddlyWiki does not also process the HTML source content for any embedded wiki-formatting syntax it may contain. This means that while you can use HTML formatted content, you cannot mix wiki-formatted content within the HTML formatting.
!!!!!Usage
<<<
The ~HTMLFormatting plugin allows you to freely ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
When a tiddler is about to be displayed, ~TiddlyWiki looks for tiddler content contained within ''<{{{html}}}>'' and ''<{{{/html}}}>'' HTML tags. This content (if any) is passed directly to the browser's internal "rendering engine" to process as ~HTML-formatted content. Once the HTML formatting has been processed, all the pieces of text occuring in between the HTML formatting are then processed by the ~TiddlyWiki rendering engine, one piece at a time, so that normal wiki-style formatting can be applied to the individual text pieces.
<<<
!!!!!Line breaks
<<<
One major difference between Wiki formatting and HTML formatting is how "line breaks" are processed. Wiki formatting treats all line breaks as literal content to be displayed //as-is//. However, because HTML normally ignores line breaks and actually processes them as simple "word separators" instead, many people who write HTML include extra line breaks in their documents, just to make the "source code" easier to read.
Even though you can use HTML tags within your tiddler content, the default treatment for line breaks still follows the Wiki-style rule (i.e., all new lines are displayed as-is). When adding HTML content to a tiddler (especially if you cut-and-paste it from another web page), you should take care to avoid adding extra line breaks to the text.
If removing all the extra line breaks from your HTML content would be a big hassle, you can quickly //override the default Wiki-style line break rule// so that the line breaks use the standard HTML rules instead. Placing a ''<{{{hide linebreaks}}}>'' tag within the tiddler's HTML content changes all line breaks to spaces before rendering the content, so that the literal line breaks will be processed as simple word-breaks instead.
Note: this does //not// alter the actual tiddler content that is stored in the document, just the manner in which it is displayed. Any line breaks contained in the tiddler will still be there when you edit its content. Also, to include a literal line break when the ''<{{{hide linebreaks}}}>'' tag is present, you will need to use a ''<{{{br}}}>'' or ''<{{{p}}}>'' HTML tag instead of simply typing a line break.
<<<
!!!!!How it works
<<<
The TW core support for HTML does not let you put ANY wiki-style syntax (including TW macros) *inside* the {{{<html>...</html>}}} block. Everything between {{{<html>}}} and {{{</html>}}} is handed to the browser for processing and that is it. Fortunately, this plugin ADDS the ability to let you put wiki-syntax (including macros) inside the html. It does this by first giving the tiddler source content to the browser to process the HTML, and then handling any wiki-based syntax that remains afterward.
However, not all wiki syntax can be safely passed through the browser's parser. Specifically, any TW macros inside the HTML will get 'eaten' by the browser since the macro brackets, {{{<<...>>}}} use the "<" and ">" that normally delimit the HTML/XML syntax recognized by the browser's parser.
Similarly, you can't use InlineJavascript within the HTML because the {{{<script>...</script>}}} syntax will also be consumed by the browser and there will be nothing left to process afterward. Note: unfortunately, even though the browser removes the {{{<script>...</script>}}} sequence, it doesn't actually execute the embedded javascript code that it removes, so any scripts contained inside of <html> blocks in TW are currently being ignored. :-(
As a work-around to allow TW *macros* (but not inline scripts) to exist inside of <html> formatted blocks of content, the plugin first converts the {{{<<}}} and {{{>>}}} into "%%(" and ")%%", making them "indigestible" so they can pass unchanged through the belly of the beast (the browser's HTML parser).
After the browser has done its job, the wiki syntax sequences (including the "undigested" macros) are contained in #text nodes in the browser-generated DOM elements. The plugin then recursively locates and processes each #text node, converts the %%( and )%% back into {{{<<}}} and {{{>>}}}, passes the result to wikify() for further rendering of the wiki-formatted syntax into a containing SPAN that replaces the previous #text node. At the end of this process, none of the encoded %%( and )%% sequences remain in the rendered tiddler output.
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''HTMLFormattingPlugin'' (tagged with <<tag systemConfig>>)
^^documentation and javascript for HTMLFormatting handling^^
<<<
!!!!!Revision History
<<<
''2007.12.04 [*.*.*]'' update for TW2.3.0: replaced deprecated core functions, regexps, and macros
''2007.06.14 [2.1.5]'' in formatter, removed call to e.normalize(). Creates an INFINITE RECURSION error in Safari!!!!
''2006.09.10 [2.1.4]'' update formatter for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
''2006.05.28 [2.1.3]'' in wikifyTextNodes(), decode the *value* of TEXTAREA nodes, but don't wikify() its children. (thanks to "ayj" for bug report)
''2006.02.19 [2.1.2]'' in wikifyTextNodes(), put SPAN element into tiddler DOM (replacing text node), BEFORE wikifying the text content. This ensures that the 'place' passed to any macros is correctly defined when the macro is evaluated, so that calls to story.findContainingTiddler(place) will work as expected. (Thanks for bug report from GeoffSlocock)
''2006.02.05 [2.1.1]'' wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
''2005.12.01 [2.1.0]'' don't wikify #TEXT nodes inside SELECT and TEXTAREA elements
''2005.11.06 [2.0.1]'' code cleanup
''2005.10.31 [2.0.0]'' replaced hijack wikify() with hijack config.formatters["html"] and simplified recursive WikifyTextNodes() code
''2005.10.09 [1.0.2]'' combined documentation and code into a single tiddler
''2005.08.05 [1.0.1]'' moved HTML and CSS definitions into plugin code instead of using separate tiddlers
''2005.07.26 [1.0.1]'' Re-released as a plugin. Added <{{{html}}}>...</{{{nohtml}}}> and <{{{hide newlines}}}> handling
''2005.07.20 [1.0.0]'' Initial Release (as code adaptation)
<<<
!!!!!Credits
<<<
This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.HTMLFormatting = {major: 2, minor: 1, revision: 5, date: new Date(2007,6,14)};
// find the formatter for HTML and replace the handler
initHTMLFormatter();
function initHTMLFormatter()
{
for (var i=0; i<config.formatters.length && config.formatters[i].name!="html"; i++);
if (i<config.formatters.length) config.formatters[i].handler=function(w) {
if (!this.lookaheadRegExp) // fixup for TW2.0.x
this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var html=lookaheadMatch[1];
// optionally suppress wiki-style literal handling of newlines
// strip any carriage returns added by Internet Explorer's textarea edit field
// encode newlines as \n so Internet Explorer's HTML parser won't eat them
// encode macro brackets (<< and >>) so HTML parser won't eat them
if (html.indexOf('<hide linebreaks>')!=-1) html=html.replace(/\n/g,' ');
html=html.replace(/\r/g,'');
html=html.replace(/\n/g,'\\n');
html=html.replace(/<</g,'%%(').replace(/>>/g,')%%');
// create span to hold HTML
// parse HTML and normalize the results
// walk node tree and call wikify() on each text node
var e = createTiddlyElement(w.output,"span");
e.innerHTML=html;
// REMOVED: e.normalize(); // THIS CAUSED INFINITE RECURSION IN SAFARI
wikifyTextNodes(e);
// advance to next parse position
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
}
// wikify text nodes remaining after HTML content is processed (pre-order recursion)
function wikifyTextNodes(theNode)
{
// textarea node doesn't get wikified, just decoded...
if (theNode.nodeName.toLowerCase()=='textarea')
theNode.value=theNode.value.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n');
else for (var i=0;i<theNode.childNodes.length;i++) {
var theChild=theNode.childNodes.item(i);
if (theChild.nodeName.toLowerCase()=='option') continue;
if (theChild.nodeName.toLowerCase()=='select') continue;
wikifyTextNodes(theChild);
if (theChild.nodeName=='#text') {
var txt=theChild.nodeValue;
// decode macro brackets and newlines
txt=txt.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n');
// replace text node with wikified() span
var newNode=createTiddlyElement(null,"span");
theNode.replaceChild(newNode,theChild);
wikify(txt,newNode);
}
}
}
//}}}
<<popup Zvukovky [[<<tiddler Zvukovky$))]]>>
<<popup Počítače [[<<tiddler Počítače$))]]>>
<<popup DSP [[<<tiddler DSP$))]]>>
/***
|Name|ImageSizePlugin|
|Source|http://www.TiddlyTools.com/#ImageSizePlugin|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin,formatter|
|Requires||
|Overrides|'image' formatter|
|Description|extends image syntax to add optional CSS width/height values|
!!!!!Usage
<<<
Extends standard TiddlyWiki image syntax, ''{{{[img[...]]}}}'', so you can specify CSS width/height values.
The extended syntax is:
>''{{{[img(x,y)[...]]}}}''
>where x and y are the desired width and height of the image, specified using CSS units of measurement (e.g., px, em, cm, in, or %). Use ''auto'' for either the width or height to scale image proportionally (i.e., maintain aspect ratio). You may also calculate a CSS value on-the-fly by using //evaluated javascript//, enclosed between """{{""" and """}}""", e.g, {{{({{widthFunction()}},{{heightFunction()}})}}}.
Note: this plugin also includes enhancements to support:
*[[AttachFilePluginFormatters]] (embed image files as text-encoded tiddlers)
* [[ImagePathPlugin]] (fallback locations for missing images)
Please refer to those plugins for details...
<<<
!!!!!Examples
<<<
{{{
[<img(34%,auto)[images/meow.gif]]
[<img(21%,auto)[images/meow.gif]]
[<img(13%,auto)[images/meow.gif]]
[<img(8%,auto)[images/meow.gif]]
[<img(5%,auto)[images/meow.gif]]
[<img(3%,auto)[images/meow.gif]]
[<img(2%,auto)[images/meow.gif]]
[img(1%,auto)[images/meow.gif]]
}}}
[<img(34%,auto)[images/meow.gif]]
[<img(21%,auto)[images/meow.gif]]
[<img(13%,auto)[images/meow.gif]]
[<img(8%,auto)[images/meow.gif]]
[<img(5%,auto)[images/meow.gif]]
[<img(3%,auto)[images/meow.gif]]
[<img(2%,auto)[images/meow.gif]]
[img(1%,auto)[images/meow.gif]]
{{clear block{}}}
<<<
!!!!!Revisions
<<<
2008.01.19 [1.1.0] added support for evaluated width/height values!!
2008.01.18 [1.0.1] code cleanup plus improved regexp for matching "(width,height)" by eliminating hard-coded recognition of [px,em,cm,in,%] CSS units. Syntax now accepts ANY values for width/height, and leaves it to the browser's CSS processing to handle any invalid values.
2008.01.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.imageSize = {major: 1, minor: 1, revision: 0, date: new Date(2008,1,19)};
// replace standard handler for image formatter
// note: includes modifications for [[AttachFilePluginFormatters]] AND [[ImagePathPlugin]]
var f=config.formatters.findByField("name","image");
config.formatters[f].match="\\[[<>]?[Ii][Mm][Gg](?:\\([^,]*,[^\\)]*\\))?\\[";
config.formatters[f].lookaheadRegExp=/\[([<]?)(>?)[Ii][Mm][Gg](\([^,]*,[^\)]*\))?\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg;
config.formatters[f].handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var floatLeft=lookaheadMatch[1];
var floatRight=lookaheadMatch[2];
var XY=lookaheadMatch[3];
var tooltip=lookaheadMatch[4];
var src=lookaheadMatch[5];
var link=lookaheadMatch[6];
// Simple bracketted link
var e = w.output;
if(link) { // LINKED IMAGE
if (config.formatterHelpers.isExternalLink(link)) {
if (config.macros.attach && config.macros.attach.isAttachment(link)) {
// see [[AttachFilePluginFormatters]]
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title = config.macros.attach.linkTooltip + link;
} else
e = createExternalLink(w.output,link);
} else
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
addClass(e,"imageLink");
}
var img = createTiddlyElement(e,"img");
if(floatLeft) img.align="left"; else if(floatRight) img.align="right"; // FLOAT LEFT/RIGHT
if(XY) { // CUSTOM SIZE with optional EVAL'ED width/height ({{...}},{{...}})
var parts=XY.replace(/[\(\)]/g,'').split(","); var x=parts[0]; var y=parts[1];
if (x.substr(0,2)=="{{") {
try{img.style.width=eval(x.substr(2,x.length-4));}
catch(e){displayMessage(e.description||e.toString())}
} else img.style.width=x;
if (y.substr(0,2)=="{{") {
try{img.style.height=eval(y.substr(2,y.length-4));}
catch(e){displayMessage(e.description||e.toString())}
} else img.style.height=y;
}
if(tooltip) img.title = tooltip; // TOOLTIP
// GET IMAGE SOURCE (get attachment or resolve fallback path as needed)
if (config.macros.attach && config.macros.attach.isAttachment(src))
src=config.macros.attach.getAttachment(src); // see [[AttachFilePluginFormatters]]
else if (config.formatterHelpers.resolvePath) { // see [[ImagePathPlugin]]
// Note: IE and Safari use onError to call resolvePath() only if initial lookup fails
// (avoids security messages for initial filesystem access)... otherwise, attempt to
// resolve the original path/file before initial rendering
if (config.browser.isIE || config.browser.isSafari) {
img.onerror=(function(){
this.src=config.formatterHelpers.resolvePath(this.src,false);
return false;
});
} else
src=config.formatterHelpers.resolvePath(lookaheadMatch[5],true);
}
img.src=src; // RENDER IMAGE
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
//}}}
/***
|Name|JumpMacro|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#JumpMacro|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Macro version of the core jump command, that also provides an optional 'jump to top' button.
!Demo:
click the 'j' button in the hoverMenu on the right.
!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
!Usage
{{{<<jump>>}}}<<jump>>
{{{<<jump customlabel customtooltip top>>}}} <<jump customlabel customtooltip top>>
Note: passing the third parameter as top, enables the 'top' button in the dropdown.
!History:
27-07-06, ver1.0
!Code
***/
//{{{
config.macros.jump= {};
config.macros.jump.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
var label = (params[0] && params[0]!=".")? params[0]: 'jump';
var tooltip = (params[1] && params[1]!=".")? params[1]: 'jump to an open tiddler';
var top = (params[2] && params[2]=='top') ? true: false;
var btn =createTiddlyButton(place,label,tooltip,this.onclick);
if (top==true)
btn.setAttribute("top","true")
}
config.macros.jump.onclick = function(e)
{
if (!e) var e = window.event;
var theTarget = resolveTarget(e);
var top = theTarget.getAttribute("top");
var popup = Popup.create(this);
if(popup)
{
if(top=="true")
{createTiddlyButton(createTiddlyElement(popup,"li"),'Top ↑','Top of TW',config.macros.jump.top);
createTiddlyElement(popup,"hr");}
story.forEachTiddler(function(title,element) {
createTiddlyLink(createTiddlyElement(popup,"li"),title,true);
});
}
Popup.show(popup,false);
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return false;
}
config.macros.jump.top = function()
{
window.scrollTo(0,0);
}
//}}}
/***
|''Name:''|LegacyStrikeThroughPlugin|
|''Description:''|Support for legacy (pre 2.1) strike through formatting|
|''Version:''|1.0.2|
|''Date:''|Jul 21, 2006|
|''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|
|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.0|
***/
//{{{
// Ensure that the LegacyStrikeThrough Plugin is only installed once.
if(!version.extensions.LegacyStrikeThroughPlugin) {
version.extensions.LegacyStrikeThroughPlugin = {installed:true};
config.formatters.push(
{
name: "legacyStrikeByChar",
match: "==",
termRegExp: /(==)/mg,
element: "strike",
handler: config.formatterHelpers.createElementAndWikify
});
} //# end of "install only once"
//}}}
/***
| Name|LessBackupsPlugin|
| Description|Intelligently limit the number of backup files you create|
| Version|3.0 ($Rev: 2320 $)|
| Date|$Date: 2007-06-18 22:37:46 +1000 (Mon, 18 Jun 2007) $|
| Source|http://mptw.tiddlyspot.com/#LessBackupsPlugin|
| Author|Simon Baird|
| Email|simon.baird@gmail.com|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
!!!Description
You end up with just backup one per year, per month, per weekday, per hour, minute, and second. So total number won't exceed about 200 or so. Can be reduced by commenting out the seconds/minutes/hours line from modes array
!!!Notes
Works in IE and Firefox only. Algorithm by Daniel Baird. IE code by by Saq Imtiaz.
!!!Code
***/
//{{{
window.getSpecialBackupPath = function(backupPath) {
var MINS = 60 * 1000;
var HOURS = 60 * MINS;
var DAYS = 24 * HOURS;
// comment out the ones you don't want
var modes = [
["YYYY", 365*DAYS], // one per year for ever
["MMM", 31*DAYS], // one per month
["ddd", 7*DAYS], // one per weekday
//["d0DD", 1*DAYS], // one per day of month
["h0hh", 24*HOURS], // one per hour
["m0mm", 1*HOURS], // one per minute
["s0ss", 1*MINS], // one per second
["latest",0] // always keep last version. (leave this).
];
var now = new Date();
for (var i=0;i<modes.length;i++) {
// the filename we will try
var specialBackupPath = backupPath.replace(/(\.)([0-9]+\.[0-9]+)(\.html)$/,
'$1'+now.formatString(modes[i][0]).toLowerCase()+'$3')
// open the file
try {
if (config.browser.isIE) {
var fsobject = new ActiveXObject("Scripting.FileSystemObject")
var fileExists = fsobject.FileExists(specialBackupPath);
if (fileExists) {
var fileObject = fsobject.GetFile(specialBackupPath);
var modDate = new Date(fileObject.DateLastModified).valueOf();
}
}
else {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(specialBackupPath);
var fileExists = file.exists();
if (fileExists) {
var modDate = file.lastModifiedTime;
}
}
}
catch(e) {
// give up
return backupPath;
}
// expiry is used to tell if it's an 'old' one. Eg, if the month is June and there is a
// June file on disk that's more than an month old then it must be stale so overwrite
// note that "latest" should be always because the expiration period is zero (see above)
var expiry = new Date(modDate + modes[i][1]);
if (!fileExists || now > expiry)
return specialBackupPath;
}
}
// hijack the core function
window.getBackupPath_orig = window.getBackupPath;
window.getBackupPath = function(localPath) {
return getSpecialBackupPath(getBackupPath_orig(localPath));
}
//}}}
''Open Source License''
VisualTW and TiddlyWiki are published under a BSD [[open source license|http://en.wikipedia.org/wiki/Open_source_license]]. This gives you the freedom to use it pretty much however you want, including for commercial purposes, as long as you keep the copyright notice. If you do use stuff from this page a links back to http://visualtw.ouvaton.org/VisualTW.html and to http://www.tiddlywiki.com/ are appreciated.
<html><p>It seems Firefox doesn't apply styles on links while there are edited in wysiwyg mode. The default color and underline style can be changed using <a href="about:config">about:config</a> url to change browser.underline_anchors and browser.anchor_color (this apply on all pages).
</p><p>Obviously, this is an ugly way to solve this problem</p></html>
Recording studio, where I'm recording all of my scenic music + recording studio for vocals.
* Computers:
** Apple MacBook Pro 2.4GHz Intel Core 2 Duo, 4GB of RAM
** Museresearch Receptor (IK Multimedia Total Workstation Rack)
* Soundcards:
** Steinberg MR816 CSX
** M-Audio FireWire 1814
* Sequencers:
** Logic Pro 8
** MOTU Digital Performer 6
** Steinberg Cubase 5
* DSP processors:
** UAD-Xpander
** T.C.Ellectronic PowerCore Compact
* SW synths:
** EastWest/Quantum Leap Symphonic Orchestra Platinum/Gold Pro/Silver
** EastWest/Quantum Leap Symphonic Choirs
** EastWest/Quantum Leap Voicess of Passions
** EastWest/Quntum Leap Goliath
** EastWest/Quntum Leap SD2
** EastWest/Quntum Leap Pianos
** Native Instruments KOMPLETE 5
** IK Multimedia Total Workstation 2
** MOTU Symphonic
** KORG Legacy Collection Digital Edition
** GForce synths
** ...
* HW synths:
** ROLAND V-Synth GT
** YAMAHA SY-99
* Controllers:
** Euphonix MC Control
** Tascam US-2400
** Frontier TranzPort
** Doepfer R2M
* Speakers & Headphones:
** Tannoy System 600A
** Beyerdynamic DT 990 Pro
** KOSS R/80
* Room Correction:
** IK Multimedia ARC System
* Mic:
** RODE NT1-A
*HW Processors:
** TL-Audio Fatman Fat-1
I'm creating anglish-czech dictionary of words used in recordnig studios.
I'm working on websites about using computers in recording studios: [[Audio-Mac.cz|http://www.audio-mac.cz]] and [[Audio-PC.cz|http://www.audio-pc.cz]].
[[Martin Jirsak MAJ|Martin Jirsák MAJ]]
<<fontSize font-size: >>
----
[[My Music|Music]]
[[MAJ Studio|MAJ Studio]]
[[Recording Studio Consalting|Recording Studio Consalting]]
[[Articles|Articles]]
[[MIDI Dictionary|MIDI Dictionary]]
[[Synthesis of czech speech|Synthesis of czech speech]]
----
[[Contact|Contact]]
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<script type="text/javascript" src="fckeditor/fckeditor.js"></script>
<!--}}}-->
<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>Martin Jirsak MAJ - music composer</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:blue;">Requres Javascript.</span></div>
<html>
''Martin Jirsak MAJ'' - I'm film, scenic, thatre and dramatic music composer.
[[This is my music|Music]].
Motto: Music is one of the best tool for evoke the atmosphere.
TiddlyWiki.com - official release
http://www.TiddlyWiki.com
----
TiddlyWiki.org - wiki, tickets, source control
http://www.TiddlyWiki.org
----
GoogleGroup: TiddlyWiki - user/author discussion
http://groups.google.com/group/TiddlyWiki/
----
GoogleGroup: TiddlyWikiDev - core/plugin discussion
http://groups.google.com/group/TiddlyWikiDev/
----
TiddlyVault - index of add-ons from many sources
http://TiddlyVault.TiddlySpot.com
----
TiddlySpot - instant TiddlyWiki hosting!!
http://www.TiddlySpot.com
----
TiddlyTools - plugins, scripts, templates, etc.
http://www.TiddlyTools.com
----
del.icio.us - find popular TiddlyWiki sites
http://del.icio.us/tag/tiddlywiki
flash games...
----
Rag Doll
http://www.planetdan.net/pics/misc/georgerag.swf
----
Asteroids
http://www.80smusiclyrics.com/games/asteroids.swf
----
PacMan
http://www.80smusiclyrics.com/games/pacman.swf
----
Tetris
http://www.80smusiclyrics.com/games/tetris2.swf
----
Simon
http://www.80smusiclyrics.com/games/simon.swf
flickr photos...
----
HDR Pool (public collection)
http://www.flickr.com/groups/hdr/pool/show/
----
favorite videos...
----
"PovertyUSA" - WATCH THIS!
http://www.nccbuscc.org/cchd/povertyusa/tour.swf
----
Jack W counts (1yr old)
http://wolfram.org/media/jack_20050310_cleaned.mov
----
webcams...
----
Times Square
http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx
----
Monterey Bay
http://www.mbayaq.org/media/STRM/mba_mbay.asx
----
Wrightsville Beach, North Carolina
http://www.aroundtownnc.com/wvx/beachcam.wvx
----
Koningsplein, Amsterdam
mms://rembrandt.terena.nl/stream2
----
Corsica
http://195.6.173.164/liensmedias/webcam.asx
----
Kulak's Woodshed: Live/Recorded acoustic music
http://www.kulakswoodshed.com/high.asx
----
news...
----
BBC News24 - Live
http://www.bbc.co.uk/newsa/n5ctrl/live/nb/rm/video/now2_nb.ram
----
BBC News - London Summary
http://www.bbc.co.uk/london/realmedia/news/tvnews.ram
----
BBC Entertainment News
http://www.bbc.co.uk/newsa/n5ctrl/summaries/entertain/bb_liquid_news.ram
----
Bloomberg Business News
http://www.bloomberg.com/streams/video/LiveBTV200.ram
----
movies (AmericaFree.TV)...
----
Classic Comedy
http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov
----
Classic Movies
http://www.americafree.tv/unicast_mov/AmericaFreeTVClassics.mov
----
"B" Movies
http://www.americafree.tv/unicast_mov/AmericaFreeTVDimensionB.mov
----
science/education/govt...
----
PBS: Annenberg/CPB
http://www.scctv.net/annenberg_broadband.asx
----
NASA TV
http://science.ksc.nasa.gov/video/nasatv/nasatv.asx
----
C-SPAN 1
http://play.rbn.com/play.asx?url=cspan/cspan/wmlive/cspan1v.asf&proto=mms?mswmext=.asx
----
C-SPAN 2
http://play.rbn.com/play.asx?url=cspan/cspan/wmlive/cspan2v.asf&proto=mms?mswmext=.asx
----
C-SPAN 3
http://play.rbn.com/play.asx?url=cspan/cspan/wmlive/cspan3v.asf&proto=mms?mswmext=.asx
news and events...
----
News - CNN
http://www.cnn.com
----
News - BBC
http://news.bbc.co.uk
----
Comics
http://www.unitedmedia.com/comics/
----
Television
http://www.tvguide.com/listings/default.aspx
----
Weather
http://www.wunderground.com/US/CA/Sunnyvale.html
----
Earthquakes
http://quake.wr.usgs.gov/recenteqs/latest.htm
----
Maps
http://maps.google.com
BT/Osmosoft...
----
Jeremy Ruston
http://jermolene.wordpress.com/
----
Andrew Back
http://carrierdetect.com/
----
Fred Dohr
http://fnd.lewcid.org/blog/
----
James Shi
http://curiousjames.wordpress.com/
----
Jon Lister
http://jaybyjayfresh.com/
----
Nick Webb
http://www.erraticmusings.com/
----
Paul Downey
http://blog.whatfettle.com/
----
Phil Hawksworth
http://www.hawksworx.com/journal/
----
Phil Whitehouse
http://philwhitehouse.blogspot.com/
----
Simon McManus
http://simonmcmanus.com/
technical references...
----
Javascript QuickRef (DevGuru)
http://www.devguru.com/technologies/javascript/
----
CSS QuickRef (DevGuru)
http://www.devguru.com/technologies/css2/
----
CSS compatibility chart
http://www.webdevout.net/browser-support-css
----
Unicode Character Charts
http://www.alanwood.net/unicode/
----
UTF-8 Encoding (Wikipedia)
http://en.wikipedia.org/wiki/UTF-8
----
HTML Character entities (W3)
http://www.w3.org/TR/REC-html40/sgml/entities.html
----
Mozilla Developer Center
http://developer.mozilla.org/
----
Gecko DOM Reference
http://developer.mozilla.org/en/docs/Gecko_DOM_Reference
----
IP Lookup...
----
ARIN - North America
http://www.arin.net
----
RIPE - Europe
http://www.ripe.net
----
APNIC - Asia/Pacific
http://www.apnic.net
----
LACNIC - Latin America/Caribbean
http://www.lacnic.net
----
AFRINIC - Africa
http://www.afrinic.net
/***
|Name|MoveablePanelPlugin|
|Source|http://www.TiddlyTools.com/#MoveablePanelPlugin|
|Documentation|http://www.TiddlyTools.com/#MoveablePanelPluginInfo|
|Version|2.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|NestedSlidersPlugin|
|Overrides||
|Description|drag/stretch 'floating sliders' and other page elements|
Adds move and size mouse event handling and fold/unfold, and close/dock toolbar command items to any floating slider panel or tiddler element
!!!!!Documentation
>see [[MoveablePanelPluginInfo]]
!!!!!Revisions
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.30 [2.1.0] added 'noedges' option for alternative 'grab handles' (top=move, bottom-right=resize)
|please see [[MoveablePanelPluginInfo]] for additional revision details|
''2006.03.04 [1.0.0]'' Initial public release
<<<
!!!!!Code
***/
//{{{
version.extensions.moveablePanel= {major: 2, minor: 1, revision: 0, date: new Date(2007,12,30)};
//}}}
//{{{
config.macros.moveablePanel= {
handler: function(place,macroName,params) {
var p=this.getPanel(place); if (!p) return;
var showfold=true; var showclose=true; var showhover=true;
var noedges=false; var param=null;
while (param=params.shift()) { param=param.toLowerCase();
if (param=="noclose") showclose=false;
if (param=="nofold") showfold=false;
if (param=="nohover") showhover=false;
if (param=="noedges") noedges=true;
}
if (!p.saved) p.saved= { // remember original panel event handlers, size, location, border
mouseover: p.onmouseover, mouseout: p.onmouseout, dblclick: p.ondblclick,
top: p.style.top, left: p.style.left, width: p.style.width, height: p.style.height,
position: p.style.position, border: p.style.border, title: p.title,
transient: p.getAttribute("transient")
};
// create control menu items
var html='<div class="toolbar" style="display:none;position:absolute;';
html+=(hasClass(p,"floatingPanel")?'right:1em;top:1em;':'right:.5em;top:-1em;')+'">';
var s='border:1px solid #666;background:#ccc;color:#666 !important;padding:0px .25em;-moz-border-radius:0px';
if (showfold)
html+='<a href="javascript:;" title="FOLD: reduce panel size" style="'+s+'"'
+' onclick="return config.macros.moveablePanel.foldPanel(this,event)">−</a>';
if (showhover)
html+='<a href="javascript:;" title="SCROLLING: panel moves with page" style="'+s+'"'
+' onclick="return config.macros.moveablePanel.hoverPanel(this,event)">=</a>';
if (showclose) {
if (hasClass(p,"floatingPanel"))
html+='<a href="javascript:;" title="CLOSE: hide panel and reset size/position" style="'+s+'"'
+' onclick="return config.macros.moveablePanel.closePanel(this,event)">X</a>';
else
html+='<a href="javascript:;" title="DOCK: reset panel size/position" style="'+s+'"'
+' onclick="return config.macros.moveablePanel.dockPanel(this,event)">√</a>';
}
html+='</div>';
p.menudiv=createTiddlyElement(place,"span");
p.menudiv.innerHTML=html;
// init mouse handling and tooltip
p.setAttribute("noedges",noedges?"true":"false"); // for alternative mouseover/drag handling
p.onmousemove=function(event) { return config.macros.moveablePanel.setCursorPanel(this,event); };
p.onmousedown=function(event) { return config.macros.moveablePanel.moveOrSizePanel(this,event); };
p.ondblclick=function(event) { // DOUBLE-CLICK = DOCK
if (p.getAttribute("noedges")=="true" && !((isTop&&!isLeft&&!isRight)||(isBottom&&isRight))) // not over grab handles
return p.saved.dblclick?p.saved.dblclick.apply(this,arguments):true;
if (!config.macros.moveablePanel.isEdge(this,event)) // not over edge
return p.saved.dblclick?p.saved.dblclick.apply(this,arguments):true;
if (config.macros.moveablePanel.dockPanel(this,event)) // not docking
return p.saved.dblclick?p.saved.dblclick.apply(this,arguments):true;
else return false; // docked... done.
};
p.onmouseover=function(event) { // MOUSEOVER = SHOW MENU ITEMS
if(addClass instanceof Function)
addClass(this,"selected"); // so toolbar-classed items will display
if (this.getAttribute("undocked")=="true"||hasClass(this,"floatingPanel"))
this.menudiv.firstChild.style.display="inline";
if (this.saved.mouseover) return this.saved.mouseover.apply(this,arguments);
};
p.onmouseout=function(event) { // MOUSEOUT = HIDE MENU ITEMS
if(removeClass instanceof Function)
removeClass(this,"selected"); // so toolbar-classed items are hidden again
if (this.menudiv) this.menudiv.firstChild.style.display="none";
if (this.saved.mouseout) return this.saved.mouseout.apply(this,arguments);
};
// FIXUP for "floating sliders" (see NestedSlidersPlugin)
// prevent automatic trigger of adjustSliderPos() for mouse events on floating slider panel/button
// and make sure that slider button causes moveable panel to be close AND docked (if needed)
if (hasClass(p,"floatingPanel") && p.button) {
p.saved.mouseover=null; // discard previous mouse event handlers to prevent
p.saved.mouseout=null; // automatic triggering of adjustSliderPos() for mouseovers
p.button.onmouseover=null; // on slider panel and slider button
if(!p.button.saved_onclick) p.button.saved_onclick=p.button.onclick; // HIJACK SLIDER BUTTON
p.button.onclick=function(ev){
config.macros.moveablePanel.dockPanel(this.sliderPanel,ev); // DOCK PANEL FIRST...
return this.saved_onclick.apply(this,arguments); // ...THEN CLOSE IT
}
}
},
processed: function(event) {
event.cancelBubble=true; if (event.stopPropagation) event.stopPropagation(); return false;
},
getPanel: function(place) {
// find a floating panel or use containing element
var p=place; while (p && !(hasClass(p,"floatingPanel")||p.saved)) p=p.parentNode;
return p||place;
},
isEdge: function(place,event) {
if (!event) var event=window.event;
var p=this.getPanel(place); if (!p) return false;
var left=findPosX(p); var top=findPosY(p);
var width=p.offsetWidth; var height=p.offsetHeight;
var x=!config.browser.isIE?event.pageX:event.clientX;
var y=!config.browser.isIE?event.pageY:event.clientY;
if (x<left||x>=left+width||y<top||y>=top+height) return false;
var edgeWidth=10; var edgeHeight=10;
var isTop=(y-top<edgeHeight); var isLeft=(x-left<edgeWidth);
var isBottom=(top+height-y<edgeHeight); var isRight=(left+width-x<edgeWidth);
return isTop||isLeft||isBottom||isRight;
},
dockPanel: function(place,event) {
if (!event) var event=window.event;
var p=this.getPanel(place); if (!p) return true;
if (p.folded) this.foldPanel(p.foldButton,event);
if (p.hover) this.hoverPanel(p.hoverButton,event);
if (p.saved) {
p.style.top=p.saved.top; p.style.left=p.saved.left;
p.style.width=p.saved.width; p.style.height=p.saved.height;
p.style.position=p.saved.position;
if (p.saved.transient) p.setAttribute("transient","true");
p.setAttribute("undocked","");
}
if (hasClass(p,"floatingPanel") && window.adjustSliderPos) // see NestedSlidersPlugin
window.adjustSliderPos(p.parentNode,p.button,p);
return this.processed(event);
},
closePanel: function(place,event) {
var p=this.getPanel(place); if (!p) return true;
// if a slider button exists close the panel by calling slider button handler
if (p.button) { p.button.focus(); onClickNestedSlider({target:p.button}); }
return this.dockPanel(place,event); // and then reset panel state
},
foldPanel: function(place,event) {
if (!event) var event=window.event;
var p=this.getPanel(place); if (!p) return true;
if (!p.foldButton) p.foldButton=place;
if (p.folded) {
p.style.height=p.folded_savedheight;
p.style.overflow=p.folded_savedoverflow;
if (!hasClass(p,"floatingPanel")) p.menudiv.firstChild.style.top="-1em";
} else {
p.folded_savedheight=p.style.height; p.style.height="1em";
p.folded_savedoverflow=p.style.overflow; p.style.overflow="hidden";
if (!hasClass(p,"floatingPanel")) p.menudiv.firstChild.style.top="1em";
}
p.folded=!p.folded;
place.innerHTML=p.folded?"+":"−";
place.title=p.folded?"UNFOLD: restore panel size":"FOLD: reduce panel size";
return this.processed(event);
},
hoverPanel: function(place,event) {
if (!event) var event=window.event;
var p=this.getPanel(place); if (!p) return true;
if (!p.hoverButton) p.hoverButton=place;
if (p.hover) {
p.style.position=p.hover_savedposition;
if (p.getAttribute("undocked")!="true" && p.saved && p.saved.transient)
p.setAttribute("transient","true"); // see NestedSlidersPlugin
} else {
p.hover_savedposition=p.style.position; p.style.position="fixed";
if (p.saved.transient) p.setAttribute("transient","false");
}
p.hover=!p.hover;
place.innerHTML=p.hover?"^":"=";
place.title=p.hover?"HOVERING: panel stays in view when scrolling page":"SCROLLING: panel moves with page";
return this.processed(event);
},
setCursorPanel: function(place,event) {
if (!event) var event=window.event;
var p=this.getPanel(place); if (!p) return true;
var left=findPosX(p); var top=findPosY(p);
var width=p.offsetWidth; var height=p.offsetHeight;
var x=!config.browser.isIE?event.pageX:event.clientX;
var y=!config.browser.isIE?event.pageY:event.clientY;
if (x<left||x>=left+width||y<top||y>=top+height) return true; // not inside panel, let mousedown bubble through
var edgeWidth=10; var edgeHeight=10;
var isTop=(y-top<edgeHeight); var isLeft=(x-left<edgeWidth);
var isBottom=(top+height-y<edgeHeight); var isRight=(left+width-x<edgeWidth);
p.style.cursor="auto";
p.title=p.saved?p.saved.title:"";
if (!(isTop||isLeft||isBottom||isRight)) return true;
if (p.getAttribute("noedges")=="true") {
if (isTop&&!isLeft&&!isRight) {
p.style.cursor="move";
p.title="MOVE: drag top panel edge"
+(p.getAttribute("undocked")=="true"?", DOCK: double-click":"");
} else if (isBottom && isRight) {
p.style.cursor="se-resize";
p.title="RESIZE: drag lower right corner"
+(p.getAttribute("undocked")=="true"?", DOCK: double-click":"");
}
} else {
p.style.cursor=!event.shiftKey?"move":((isTop?'n':(isBottom?'s':''))+(isLeft?'w':(isRight?'e':''))+'-resize');
p.title="MOVE: drag panel edge, RESIZE: hold shift key"
+(p.getAttribute("undocked")=="true"?", DOCK: double-click":"");
}
return true; // let mouseover event bubble through
},
moveOrSizePanel: function(place,event) {
if (!event) var event=window.event;
var p=this.getPanel(place); if (!p) return true;
if (!this.isEdge(place,event)) return true;
if (!p.saved) p.saved= { // remember original panel event handlers, size, location, border
mouseover: p.onmouseover, mouseout: p.onmouseout, dblclick: p.ondblclick,
top: p.style.top, left: p.style.left, width: p.style.width, height: p.style.height,
position: p.style.position, border: p.style.border, transient: p.getAttribute("transient")
};
var left=findPosX(p); var top=findPosY(p);
var width=p.offsetWidth; var height=p.offsetHeight;
var x=!config.browser.isIE?event.pageX:event.clientX;
var y=!config.browser.isIE?event.pageY:event.clientY;
var edgeWidth=10; var edgeHeight=10;
var isTop=(y-top<edgeHeight); var isLeft=(x-left<edgeWidth);
var isBottom=(top+height-y<edgeHeight); var isRight=(left+width-x<edgeWidth);
var sizing=event.shiftKey; // remember this for use during mousemove tracking
if (p.getAttribute("noedges")=="true") {
if (!((isTop&&!isLeft&&!isRight)||(isBottom&&isRight))) return true; // not over grab handle
var sizing=isBottom&&isRight;
}
var adjustLeft=0; var adjustTop=0;
// adjustment for relative container
var pp=p.parentNode; while (pp && !(pp.style&&pp.style.position=='relative')) pp=pp.parentNode;
if (pp) { adjustLeft+=findPosX(pp); adjustTop+=findPosY(pp); }
// adjustment for floating slider container
var pp=p.parentNode; while (pp && !hasClass(pp,"floatingPanel")) pp=pp.parentNode;
if (pp) { adjustLeft+=findPosX(pp); adjustTop+=findPosY(pp); }
// start tracking mousemove events
this.activepanel=p;
var target=p; // if 'capture' handling not supported, track within panel only
if (document.body.setCapture) { document.body.setCapture(); var target=document.body; } // IE
if (window.captureEvents) { window.captureEvents(Event.MouseMove|Event.MouseUp,true); var target=window; } // moz
if (target.onmousemove!=undefined) target.saved_mousemove=target.onmousemove;
target.onmousemove=function(e){
if (!e) var e=window.event;
var p=config.macros.moveablePanel.activepanel;
if (!p) { this.onmousemove=this.saved_mousemove?this.saved_mousemove:null; return; }
// PROBLEM: p.offsetWidth and p.offsetHeight do not seem to account for padding or borders
// WORKAROUND: subtract padding and border (in px) when calculating new panel width and height
// TBD: get these values from p.style... convert to px as needed.
var paddingWidth=10.6667; var paddingHeight=10.6667;
var borderWidth=1; var borderHeight=1;
var adjustWidth=-(paddingWidth*2+borderWidth*2);
var adjustHeight=-(paddingHeight*2+borderHeight*2);
if (p.style.position!="absolute"&&p.style.position!="fixed") {
// convert static/relative panel to movable absolute panel
p.style.position="absolute";
p.style.left=left+"px"; p.style.top=top+"px";
p.style.width=(width+adjustWidth)+"px"; p.style.top=(height+adjustHeight)+"px";
}
var newX=!config.browser.isIE?e.pageX:e.clientX;
var newY=!config.browser.isIE?e.pageY:e.clientY;
if (sizing) { // resize panel
// don't let panel get smaller than edge "grab" zones
var minWidth=edgeWidth*2-adjustWidth;
var minHeight=edgeHeight*2-adjustHeight;
if (p.folded) this.foldPanel(p.foldButton,e); // make sure panel is unfolded
if (isBottom) var newHeight=height+newY-y+1;
if (isTop) var newHeight=height-newY+y+1;
if (isLeft) var newWidth=width-newX+x+1;
if (isRight) var newWidth=width+newX-x+1;
if (isLeft||isRight) p.style.width=(newWidth>minWidth?newWidth:minWidth)+adjustWidth+"px";
if (isLeft) p.style.left=left-adjustLeft+newX-x+1+"px";
if (isTop||isBottom) p.style.height=(newHeight>minHeight?newHeight:minHeight)+adjustHeight+"px";
if (isTop) p.style.top=top-adjustTop+newY-y+1+"px";
p.setAttribute("undocked","true");
} else { // move panel
p.style.top=top-adjustTop+newY-y+1+"px";
p.style.left=left-adjustLeft+newX-x+1+"px";
if (p.saved && p.saved.transient) p.setAttribute("transient","false");
p.setAttribute("undocked","true");
}
var status=sizing?("size: "+p.style.width+","+p.style.height):("pos: "+p.style.left+","+p.style.top);
window.status=status.replace(/(\.[0-9]+)|px/g,""); // remove decimals and "px"
return config.macros.moveablePanel.processed(e);
};
// stop tracking mousemove events
if (target.onmouseup!=undefined) target.saved_mouseup=target.onmouseup;
target.onmouseup=function(e){
if (!e) var e=window.event;
if (this.releaseCapture) this.releaseCapture(); // IE
if (this.releaseEvents) this.releaseEvents(Event.MouseMove|Event.MouseUp); // moz
this.onmousemove=this.saved_mousemove?this.saved_mousemove:null;
this.onmouseup=this.saved_mouseup?this.saved_mouseup:null;
config.macros.moveablePanel.activepanel=null;
window.status="";
return config.macros.moveablePanel.processed(e);
};
return this.processed(event); // mousedown handled
}
};
//}}}
/***
|Name|MoveablePanelPlugin|
|Source|http://www.TiddlyTools.com/#MoveablePanelPlugin|
|Documentation|http://www.TiddlyTools.com/#MoveablePanelPluginInfo|
|Version|2.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|NestedSlidersPlugin|
|Overrides||
|Description|documentation for MoveablePanelPlugin|
Adds move and size mouse event handling and fold/unfold, and close/dock toolbar command items to any floating slider panel or tiddler element
!!!!!Usage
<<<
syntax: {{{<<moveablePanel nofold nohover noclose noedges>>}}}
where ''nofold'', ''nohover'' and ''noclose'' are optional flags to suppress display of selected commands in the moveable panel "toolbar" and ''noedges'' uses alternative 'grab handle' hot zones: top edge for moving and lower-right corner for sizing.
When the mouse is just inside the edges of the panel, the cursor will change to a "crossed-arrows" symbol, indicating that it is "moveable". Grab (click-hold) the panel anywhere in the edge area and then drag the mouse to reposition it. To resize the panel, hold the ''shift'' key before grabbing the panel: the cursor will change to a "double-arrow" symbol. Drag a side edge of the panel to stretch horizontally or vertically, or drag a corner of the panel to stretch in both dimensions at once. Double-clicking in the edge area of a panel will reset the panel to its original size and location.
When the mouse is anywhere over a panel (not just near the edge), a 'toolbar menu' appears in the ''upper right corner'', with the following command buttons:
*fold/unfold: ''fold'' temporarily reduces the panel height to show just one line of text. ''unfold'' restores the panel height.
*hover/scroll: ''hover'' causes the panel to remain in view (i.e., "fixed position") even when scrolling the rest of the page content. ''scroll'' allows the panel to revert to scrolling with the page content.
*close: ''close'' hides a panel from the page display. If you have moved/resized a panel, closing it restores its default position and size.
*dock: unlike a "floating slider" panel (see [[NestedSlidersPlugin]], a simple moveable panel does not "float" on the page until it has actually been moved from its default position. When moving a simple panel, the ''close'' command is replaced with ''dock'', which restores the tiddler to its default //non-floating// location on the page.
<<<
!!!!!Example
<<<
//using NestedSlidersPlugin 'floating panel' syntax//
//{{{
+++^30em^[panel]<<moveablePanel>>this is a headline for the panel
----
this is a moveable floating panel
with a few lines of text
as an example for you to try...
//note: this line is really long so you can see what happens to word wrapping when you re-size this panel//
===
//}}}
Try it: +++^30em^[panel]<<moveablePanel>>this is a headline for the panel
----
this is a moveable floating panel
with a few lines of text
as an example for you to try...
//note: this line is really long so you can see what happens to word wrapping when you re-size this panel//
===
<<<
!!!!!Revisions
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.30 [2.1.0] added 'noedges' option for alternative 'grab handles' (top=move, bottom-right=resize)
2007.12.17 [2.0.0] code reduction and feature cleanup: in getPanel(), removed handling for returning a tiddler element. Instead, when the macro is not in a floating panel, it will make it's containing element moveable. Removed "maximize" functionality (which was badly broken), and replaced it with "double-click=DOCK" (resets size/position without hiding panel). Changed "float/close" menu style to use absolute positioned elements instead of using "float:right" so panels don't suddenly stretch when the menu items are displayed. Also, throughout code, replaced direct comparison for className=="floatingPanel" with hasClass() test function. This allows additional classes to be used with moveable floating panels to apply custom CSS styles.
2007.06.10 [1.3.7] in handler(), mouse event handlers now use apply() to correctly invoke any previous mouse handler functions. This allows *moveable tiddlers* to still process the TW standard handlers for mouseover/out that toggle the 'selected' class used to highlight the toolbar items when the mouse is over a tiddler. Also, when setting up a moveable "floatingPanel", clear the existing "snap panel back to button location" mouseover/out event handlers (defined by NestedSlidersPlugin when the panels are created). This extends the fix from v1.3.5 (see below).
2007.06.08 [1.3.6] in getPanel(), remove unneeded check for "moveable" tag. Also, added support for "noclose" macro param, and updated documentation accordingly.
2007.06.02 [1.3.5] in handler(), if floating panel has a corresponding button element (i.e., a NestedSlider), then remove onmouseover handler from that button element, to prevent automatic "snap to original location" behavior. This allows *moveable* floating panels to maintain their placement when they have been manually re-positioned. This change is made for compatibility with [[NestedSlidersPlugin]] use of onmouseover (see entry for version 2.0.4)
2006.10.17 [1.3.4] when moving panel, adjust position for relative containing DIV
2006.05.25 [1.3.3] in closePanel(), use p.button.onclick() so that normal processing (updating slider button tooltip, access key, etc.) is performed
2006.05.11 [1.3.2] doc update
2006.05.11 [1.3.1] re-define all functions within moveablePanel object (eliminate global window.* function definitions (and some "leaky closures" in IE)
2006.05.11 [1.3.0] converted from inline javascript to true plugin
2006.05.09 [1.2.3] in closePanel(), set focus to sliderpanel button (if any)
2006.05.02 [1.2.2] in MoveOrSizePanel(), calculate adjustments for top and left when inside nested floating panels
2006.04.06 [1.2.1] in getPanel(), allow redefinition or bypass of "moveable" tag (changed from hard-coded "tearoff")
2006.03.29 [1.2.0] in getPanel(), require "tearoff" tag to enable floating tiddlers
2006.03.13 [1.1.0] added handling for floating tiddlers and conditional menu display
2006.03.06 [1.0.2] set move or resize cursor during mousetracking
2006.03.05 [1.0.1] use "window" vs "document.body" so mousetracking in FF doesn't drop the panel when moving too quickly
2006.03.04 [1.0.0] Initial public release
<<<
!!Symphonic music
* [[Meantime without name|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Smycce_tema.mp3]]
* [[My cou(w)ntry Sarka|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Ma_Vlastni_Sarka.mp3]] //(Theme from B. Smetana – My Country – Sarka)//
* [[Assembly|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Assembly_v1.mp3]]
!!Modern classical music
* [[Fractals|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Fractals.mp3]]
* [[Sibling dispute|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Pipe.mp3]]
* [[Tono|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Tono.mp3]]
* [[Family chronicle|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/jamu/Saga.mp3]]
!!Classical music
* [[C-laudo Debussy|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/c_laudo_debussy.mp3]]
* [[Piano|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Piano]]
!!Scenic music
* [[Bridge|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/divadlo/huceni.mp3]]
* [[Loop|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/divadlo/Smycka.mp3]]
* [[Asperger's Syndrome (Dramatical)|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/AS_mix.mp3]]
* [[Asperger's Syndrome (Chaotic)|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/AS_2_mix.mp3]]
* [[Asperger's Syndrome (Melodical)|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/AS_3_mix.mp3]]
* [[Are you ready to meet?|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Are_you/Are_you_ready_to_meet.mp3]]
!!Other music
* [[Pavlik|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/pavlik.mp3]]
* [[Depeche|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Depeche_32.mp3]]
* [[Ballad|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Ballad.mp3]]
* [[EsEmEs|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/esemes.mp3]]
* [[Průvodce|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Pruvodce.mp3]]
* [[Supplement aggregate|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/doplnek_mnoziny.mp3]]
* [[Darwin's mistakes|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/darvinovy_chyby.mp3]]
* [[Blandus|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/blandus.mp3]]
* [[Blader|http://www.blueboard.cz/dcounter.php?hid=hvc60i9mjx6fuc6r1esurco8nec9v7&down=true&url=http://www.majstudio.com/data/Blader.mp3]]
!!My music from SoundClick
<html>
<div style="width:200px; height:240px; border:solid #999999 1px; position:relative; overflow:hidden;">
<div style="position:absolute; left:0px; top:0px; z-index:2;">
<a href="http://www.soundclick.com/bands/default.cfm?bandid=695488">
<div style="margin:5px 0px 3px 0px; text-align:center">Now playing: Martin Jirsak MAJ</div>
<div style="width:200px; height:70px; cursor:pointer;"><img src="http://www.soundclick.com/images/elogos/SC_200.png" /></div></a>
<div id="lower"><embed src="http://www.soundclick.com/player/V2/mp3player200.swf" width="200" height="140" flashvars="bandid=695488&playType=band&ext=1&testMode=0&autoplay=0" name="MP3PlayerBasic" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" /></div></div>
<div style="position:absolute; left:0px; top:0px; z-index:1;"><img src="http://www.soundclick.com/images/elogos/SC_ExtBG200.png" /></div></div>
</html>
Translators and commentators sometimes make it sound as if Machiavelli were talking about something altogether different than the tradition, as if this were just an instance in which one word was being used for entirely different ideas. But then Machiavelli's philosophical point would be lost. Machiavelli is taking the traditional concept of virtue as natural human excellence, with all its teleological baggage, and giving it a partially new content. Excellence for a ruler is not the same thing as excellence for a citizen, and excellence for a ruler involves a willingness to engage in what would otherwise be immoral, unjust conduct, and which still may tarnish the ruler's immortal soul, even if it is necessary in the situation for the safety / glory of the patria. It is not the case that all virtues (= excellences) go together and imply one another, as Socrates optimistically believed. New conception of an old concept, not just homonyms.
<<notes>>
/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.5|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|show content in nest-able sliding/floating panels, without creating separate tiddlers for each panel's content|
!!!!!Documentation
>see [[NestedSlidersPluginInfo]]
!!!!!Configuration
<<<
<<option chkFloatingSlidersAnimate>> allow floating sliders to animate when opening/closing
>Note: This setting can cause 'clipping' problems in some versions of InternetExplorer.
>In addition, for floating slider animation to occur you must also allow animation in general (see [[AdvancedOptions]]).
<<<
!!!!!Revisions
<<<
2008.06.07 - 2.4.5 in 'onmouseover' handler for 'open on hover' slider buttons,<br>use call() method when invoking document.onclick function (avoids error in IE)
|please see [[NestedSlidersPluginInfo]] for additional revision details|
2005.11.03 - 1.0.0 initial public release. Thanks to RodneyGomes, GeoffSlocock, and PaulPetterson for suggestions and experiments.
<<<
!!!!!Code
***/
//{{{
version.extensions.nestedSliders = {major: 2, minor: 4, revision: 5, date: new Date(2008,6,7)};
// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkFloatingSlidersAnimate===undefined)
config.options.chkFloatingSlidersAnimate=false; // avoid clipping problems in IE
// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");
config.formatters.push( {
name: "nestedSliders",
match: "\\n?\\+{3}",
terminator: "\\s*\\={3}\\n?",
lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\@\\[\\>]*\\^)?)?(\\*)?(\\@)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(\\[[^\\]]*\\])?(?:\\}{3})?(\\#[^:]*\\:)?(\\>)?(\\.\\.\\.)?\\s*",
handler: function(w)
{
lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
{
var defopen=lookaheadMatch[1];
var cookiename=lookaheadMatch[2];
var header=lookaheadMatch[3];
var panelwidth=lookaheadMatch[4];
var transient=lookaheadMatch[5];
var hover=lookaheadMatch[6];
var buttonClass=lookaheadMatch[7];
var label=lookaheadMatch[8];
var openlabel=lookaheadMatch[9];
var panelID=lookaheadMatch[10];
var blockquote=lookaheadMatch[11];
var deferred=lookaheadMatch[12];
// location for rendering button and panel
var place=w.output;
// default to closed, no cookie, no accesskey, no alternate text/tip
var show="none"; var cookie=""; var key="";
var closedtext=">"; var closedtip="";
var openedtext="<"; var openedtip="";
// extra "+", default to open
if (defopen) show="block";
// cookie, use saved open/closed state
if (cookiename) {
cookie=cookiename.trim().slice(1,-1);
cookie="chkSlider"+cookie;
if (config.options[cookie]==undefined)
{ config.options[cookie] = (show=="block") }
show=config.options[cookie]?"block":"none";
}
// parse label/tooltip/accesskey: [label=X|tooltip]
if (label) {
var parts=label.trim().slice(1,-1).split("|");
closedtext=parts.shift();
if (closedtext.substr(closedtext.length-2,1)=="=")
{ key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }
openedtext=closedtext;
if (parts.length) closedtip=openedtip=parts.join("|");
else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }
}
// parse alternate label/tooltip: [label|tooltip]
if (openlabel) {
var parts=openlabel.trim().slice(1,-1).split("|");
openedtext=parts.shift();
if (parts.length) openedtip=parts.join("|");
else openedtip="hide "+openedtext;
}
var title=show=='block'?openedtext:closedtext;
var tooltip=show=='block'?openedtip:closedtip;
// create the button
if (header) { // use "Hn" header format instead of button/link
var lvl=(header.length>5)?5:header.length;
var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,buttonClass,title);
btn.onclick=onClickNestedSlider;
btn.setAttribute("href","javascript:;");
btn.setAttribute("title",tooltip);
}
else
var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,buttonClass);
btn.innerHTML=title; // enables use of HTML entities in label
// set extra button attributes
btn.setAttribute("closedtext",closedtext);
btn.setAttribute("closedtip",closedtip);
btn.setAttribute("openedtext",openedtext);
btn.setAttribute("openedtip",openedtip);
btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
btn.defOpen=defopen!=null; // save default open/closed state (boolean)
btn.keyparam=key; // save the access key letter ("" if none)
if (key.length) {
btn.setAttribute("accessKey",key); // init access key
btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
}
btn.setAttribute("hover",hover?"true":"false");
btn.onmouseover=function(ev) {
// optional 'open on hover' handling
if (this.getAttribute("hover")=="true" && this.sliderPanel.style.display=='none') {
document.onclick.call(document,ev); // close transients
onClickNestedSlider(ev); // open this slider
}
// mouseover on button aligns floater position with button
if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel);
}
// create slider panel
var panelClass=panelwidth?"floatingPanel":"sliderPanel";
if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters
var panel=createTiddlyElement(place,"div",panelID,panelClass,null);
panel.button = btn; // so the slider panel know which button it belongs to
btn.sliderPanel=panel; // so the button knows which slider panel it belongs to
panel.defaultPanelWidth=(panelwidth && panelwidth.length>2)?panelwidth.slice(1,-1):"";
panel.setAttribute("transient",transient=="*"?"true":"false");
panel.style.display = show;
panel.style.width=panel.defaultPanelWidth;
panel.onmouseover=function(event) // mouseover on panel aligns floater position with button
{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this); }
// render slider (or defer until shown)
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
if ((show=="block")||!deferred) {
// render now if panel is supposed to be shown or NOT deferred rendering
w.subWikify(blockquote?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
// align floater position with button
if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel);
}
else {
var src = w.source.substr(w.nextMatch);
var endpos=findMatchingDelimiter(src,"+++","===");
panel.setAttribute("raw",src.substr(0,endpos));
panel.setAttribute("blockquote",blockquote?"true":"false");
panel.setAttribute("rendered","false");
w.nextMatch += endpos+3;
if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
}
}
}
}
)
function findMatchingDelimiter(src,starttext,endtext) {
var startpos = 0;
var endpos = src.indexOf(endtext);
// check for nested delimiters
while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
// count number of nested 'starts'
var startcount=0;
var temp = src.substring(startpos,endpos-1);
var pos=temp.indexOf(starttext);
while (pos!=-1) { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
// set up to check for additional 'starts' after adjusting endpos
startpos=endpos+endtext.length;
// find endpos for corresponding number of matching 'ends'
while (startcount && endpos!=-1) {
endpos = src.indexOf(endtext,endpos+endtext.length);
startcount--;
}
}
return (endpos==-1)?src.length:endpos;
}
//}}}
//{{{
window.onClickNestedSlider=function(e)
{
if (!e) var e = window.event;
var theTarget = resolveTarget(e);
while (theTarget && theTarget.sliderPanel==undefined) theTarget=theTarget.parentNode;
if (!theTarget) return false;
var theSlider = theTarget.sliderPanel;
var isOpen = theSlider.style.display!="none";
// toggle label
theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");
// toggle tooltip
theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));
// deferred rendering (if needed)
if (theSlider.getAttribute("rendered")=="false") {
var place=theSlider;
if (theSlider.getAttribute("blockquote")=="true")
place=createTiddlyElement(place,"blockquote");
wikify(theSlider.getAttribute("raw"),place);
theSlider.setAttribute("rendered","true");
}
// show/hide the slider
if(config.options.chkAnimate && (!hasClass(theSlider,'floatingPanel') || config.options.chkFloatingSlidersAnimate))
anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
else
theSlider.style.display = isOpen ? "none" : "block";
// reset to default width (might have been changed via plugin code)
theSlider.style.width=theSlider.defaultPanelWidth;
// align floater panel position with target button
if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider);
// if showing panel, set focus to first 'focus-able' element in panel
if (theSlider.style.display!="none") {
var ctrls=theSlider.getElementsByTagName("*");
for (var c=0; c<ctrls.length; c++) {
var t=ctrls[c].tagName.toLowerCase();
if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
{ ctrls[c].focus(); break; }
}
}
var cookie=theTarget.sliderCookie;
if (cookie && cookie.length) {
config.options[cookie]=!isOpen;
if (config.options[cookie]!=theTarget.defOpen)
saveOptionCookie(cookie);
else { // remove cookie if slider is in default display state
var ex=new Date(); ex.setTime(ex.getTime()-1000);
document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();
}
}
// prevent SHIFT-CLICK from being processed by browser (opens blank window... yuck!)
// prevent clicks *within* a slider button from being processed by browser
// but allow plain click to bubble up to page background (to close transients, if any)
if (e.shiftKey || theTarget!=resolveTarget(e))
{ e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); }
Popup.remove(); // close open popup (if any)
return false;
}
//}}}
//{{{
// click in document background closes transient panels
document.nestedSliders_savedOnClick=document.onclick;
document.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);
if (document.nestedSliders_savedOnClick)
var retval=document.nestedSliders_savedOnClick.apply(this,arguments);
// if click was inside a popup... leave transient panels alone
var p=target; while (p) if (hasClass(p,"popup")) break; else p=p.parentNode;
if (p) return retval;
// if click was inside transient panel (or something contained by a transient panel), leave it alone
var p=target; while (p) {
if ((hasClass(p,"floatingPanel")||hasClass(p,"sliderPanel"))&&p.getAttribute("transient")=="true") break;
p=p.parentNode;
}
if (p) return retval;
// otherwise, find and close all transient panels...
var all=document.all?document.all:document.getElementsByTagName("DIV");
for (var i=0; i<all.length; i++) {
// if it is not a transient panel, or the click was on the button that opened this panel, don't close it.
if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;
// otherwise, if the panel is currently visible, close it by clicking it's button
if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button})
}
return retval;
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel) {
if (hasClass(panel,"floatingPanel")) {
var rightEdge=document.body.offsetWidth-1;
var panelWidth=panel.offsetWidth;
var left=0;
var top=btn.offsetHeight;
if (place.style.position=="relative" && findPosX(btn)+panelWidth>rightEdge) {
left-=findPosX(btn)+panelWidth-rightEdge; // shift panel relative to button
if (findPosX(btn)+left<0) left=-findPosX(btn); // stay within left edge
}
if (place.style.position!="relative") {
var left=findPosX(btn);
var top=findPosY(btn)+btn.offsetHeight;
var p=place; while (p && !hasClass(p,'floatingPanel')) p=p.parentNode;
if (p) { left-=findPosX(p); top-=findPosY(p); }
if (left+panelWidth>rightEdge) left=rightEdge-panelWidth;
if (left<0) left=0;
}
panel.style.left=left+"px"; panel.style.top=top+"px";
}
}
//}}}
//{{{
// TW2.1 and earlier:
// hijack Slider stop handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function()
{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }
// TW2.2+
// hijack Morpher stop handler so sliderPanel/floatingPanel overflow is visible after animation has completed
if (version.major+.1*version.minor+.01*version.revision>=2.2) {
Morpher.prototype.coreStop = Morpher.prototype.stop;
Morpher.prototype.stop = function() {
this.coreStop.apply(this,arguments);
var e=this.element;
if (hasClass(e,"sliderPanel")||hasClass(e,"floatingPanel")) {
// adjust panel overflow and position after animation
e.style.overflow = "visible";
if (window.adjustSliderPos) window.adjustSliderPos(e.parentNode,e.button,e);
}
};
}
//}}}
//{{{
config.options.chkHttpReadOnly = false;
readOnly = false;
//}}}
/***
|''Name:''|~PopupMacro|
|''Version:''|1.0.0 (2006-05-09)|
|''Source:''|http://tw.lewcid.org/#PopupMacro|
|''Author:''|Saq Imtiaz|
|''Description:''|Create popups with custom content|
|''Documentation:''|[[PopupMacro Documentation|PopupMacroDocs]]|
|''~Requires:''|TW Version 2.0.8 or better|
***/
// /%
{{{
config.macros.popup = {};
config.macros.popup.arrow = (document.all?"▼":"▾");
config.macros.popup.handler = function(place,macroName,params,wikifier,paramString,theTiddler) {
if (!params[0] || !params[1])
{createTiddlyError(place,'missing macro parameters','missing label or content parameter');
return false;};
var label = params[0];
var source = (params[1]).replace(/\$\)\)/g,">>");
var nestedId = params[2]? params[2]: 'nestedpopup';
var onclick = function(event) {
if(!event){var event = window.event;}
var theTarget = resolveTarget(event);
var nested = (!isNested(theTarget));
if ((Popup.stack.length > 1)&&(nested==true)) {Popup.removeFrom(1);}
else if(Popup.stack.length > 0 && nested==false) {Popup.removeFrom(0);};
var theId = (nested==false)? "popup" : nestedId;
var popup = createTiddlyElement(document.body,"ol",theId,"popup",null);
Popup.stack.push({root: button, popup: popup});
wikify(source,popup);
Popup.show(popup,true);
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return false;
}
var button = createTiddlyButton(place, label+this.arrow,label, onclick, null);
};
window.isNested = function(e) {
while (e != null) {
var contentWrapper = document.getElementById("contentWrapper");
if (contentWrapper == e) return true;
e = e.parentNode;
}
return false;
};
setStylesheet(
".popup, .popup a, .popup a:visited {color: #fff;}\n"+
".popup a:hover {background: #014; color: #fff; border: none;}\n"+
".popup li , .popup ul, .popup ol {list-style:none !important; margin-left:0.3em !important; margin-right:0.3em; font-size:100%; padding-top:0.5px !important; padding:0px !important;}\n"+
"#nestedpopup {background:#2E5ADF; border: 1px solid #0331BF; margin-left:1em; }\n"+
"",
"CustomPopupStyles");
config.shadowTiddlers.PopupMacroDocs="The documentation is available [[here.|http://tw.lewcid.org/#PopupMacroDocs]]";
}}}
//%/
Juchůů Some previous versions of VisualTW are available [[here|http://visualtw.ouvaton.org/old/]]
/%
|Name|QuickSearchPopup|
|Source|http://www.TiddlyTools.com/#QuickSearchPopup|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|SearchOptionsPlugin, StickyPopupPlugin|
|Overrides||
|Description|popup list of tiddlers containing text matching specified text or current tiddler title|
Usage: <<tiddler QuickSearchPopup with: "searchtext" "label">>
Note: searchtext is optional, and defaults to current tiddler title (if any)
%/<html><hide linebreaks><a href="javascript:;" class="TiddlyLink"
title="list tiddlers containing matching text"
onmouseover="var t='$1';
if (t=='$'+'1') {
var here=story.findContainingTiddler(this); if (!here) return;
var t=here.getAttribute('tiddler');
}
this.title=t.length?('list tiddlers containing text: \''+t+'\''):'disabled: no text to match';
"
onclick="var t='$1';
if (t=='$'+'1') {
var here=story.findContainingTiddler(this); if (!here) return;
var t=here.getAttribute('tiddler');
}
if (!t.length) return;
var p=Popup.create(this); if (!p) return;
addClass(p,'sticky');
var d=createTiddlyElement(p,'div');
d.style.whiteSpace='normal';
d.style.width='auto';
d.style.padding='2px';
wikify('\<\<search [['+t+']] report=summary+list [[$2\n----\n]]\>\>',d);
Popup.show(p,false);
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return(false);
">$2</a></html>
* personal
* presentations
* e-mail (Martin at-sign Jirsak dot com)
* ICQ
* Skype
Alphabetized list of producer, whose products I use and can operate with:
* Ableton
* Antares
* Apple
* Audiffex
* Behringer
* CME
* Digidesign
* Eastwest
* Evolution
* Frontier
* GEM
* Gforce
* IK Multimedia
* KAWAI
* KORG
* KURZWEIL
* M−Audio
* Mackie
* Moog
* MOTU
* Muse Research
* Native Instruments
* R.M.E.
* RODE
* ROLAND
* Sibelius
* SONY
* Steinberg
* Tascam
* TC Electronic
* Waldorf
* Waves
* YAMAHA
/***
|Macro|redirect (alias)|
|Author|[[Clint Checketts]] and Paul Petterson|
|Version|1.1 Jan 26, 2006|
|Location|http://checkettsweb.com/styles/themes.htm#RedirectMacro|
|Description|This macro tells TW to find all instances of a word and makes it point to a different link. For example, whenever I put the word 'Clint' in a tiddler I want TiddlyWiki to turn it into a link that points to a tiddler titled 'Clint Checketts' Or the word 'TW' could point to a tiddler called 'TiddlyWiki' It even matches clint (which is lowercase) [[Clint]] leet lEEt LEET|
|Usage|{{{<<redirect TW TiddlyWiki>>}}} |
|Example|<<redirect TW "TiddlyWiki">> <<redirect Clint "Clint Checketts">> (Nothing should appear, its just setting it all up)<<redirectExact lEEt Elite>>|
!Revisions
1.1- Fixed tiddler refresh so a tiddler declaring a redirect will also render the redirect
1.0- Updated to work with TiddlyWiki 2.0 (thanks to Udo Borkowski)
0.9- Original release October 2005
!Code
***/
//{{{
version.extensions.redirectExact = {major: 1, minor: 2, revision: 0, date: new Date(2005,10,24)};
config.macros.redirectExact = {label: "Pickles Rock!"};
config.macros.redirectExact.handler = function(place,macroName,params,wikifier,paramString,tiddler){
config.macros.redirect.handler(place,macroName,params,wikifier,paramString,tiddler);
}
version.extensions.redirect = {major: 1, minor: 2, revision: 0, date: new Date(2005,10,24)};
config.macros.redirect = {label: "Pickles Rock!"};
config.macros.redirect.handler = function(place,macroName,params,wikifier,paramString,tiddler){
var redirectExists = false
// Check to see if the wikifier exists
for (var i=0;i<config.formatters.length;i++)
if (config.formatters[i].name == "redirect"+params[0])
redirectExists = true;
//If it doesn't exist, add it!
if (!redirectExists){
for( var i=0; i<config.formatters.length; i++ )
if ( config.formatters[i].name=='wikiLink') break ;
if ( i >= config.formatters.length ) {
var e = "Can't find formatter for wikiLink!" ;
displayMessage( e ) ;
throw( e ) ;
}
var pattern;
if (macroName == 'redirect'){pattern=params[0].escapeRegExp().replace(/([A-Z])/img, function($1) {return("["+$1.toUpperCase()+$1.toLowerCase()+"]");});
} else {
pattern=params[0].escapeRegExp();
}
config.formatters.splice( i, 0, {
name: "redirect"+params[0],
match: "(?:\\b)(?:\\[\\[)?"+pattern+"(?:\\]\\])?(?:\\b)",
subst: params[1],
handler: function(w) {
var link = createTiddlyLink(w.output,this.subst,false);
w.outputText(link,w.matchStart,w.nextMatch);
}
});
formatter = new Formatter(config.formatters); //update the tiddler
if(tiddler) story.refreshTiddler(tiddler.title,null,true); //refresh tiddler so the new rule is applied
} // End if
}
//}}}
/***
|Name|SearchOptionsPlugin|
|Source|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#SearchOptionsPluginInfo|
|Version|2.8.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.search, TiddlyWiki.prototype.search, config.macros.search.onKeyPress|
|Options|##Configuration|
|Description|extend core search function with additional user-configurable options|
Extend core search function with additional user-configurable options including selecting which data items to search, enabling/disabling incremental key-by-key searches, and generating a ''list of matching tiddler'' instead of immediately displaying all matches. This plugin also adds syntax for rendering 'search links' within tiddler content to embed one-click searches using pre-defined 'hard-coded' search terms.
!!!!!Documentation
>see [[SearchOptionsPluginInfo]]
!!!!!Configuration
<<<
Search in:
<<option chkSearchTitles>> titles <<option chkSearchText>> text <<option chkSearchTags>> tags <<option chkSearchFields>> fields <<option chkSearchShadows>> shadows
<<option chkSearchList>> Show list of matches in [[SearchResults]]
<<option chkSearchIncremental>> Incremental (key-by-key) searching
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchByDate>> Sort matching tiddlers by date
<<<
!!!!!Revisions
<<<
2008.08.12 [2.8.2] change default for chkSearchByDate back to FALSE, and adjusted "list" and "again" output formats (minor tweaks requested by PhilWhitehouse for use on TiddlyWiki.com)
|please see [[SearchOptionsPluginInfo]] for additional revision details|
2005.10.18 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.searchOptions = {major: 2, minor: 8, revision: 2, date: new Date(2008,8,12)};
if (config.options.chkSearchTitles===undefined) config.options.chkSearchTitles=true;
if (config.options.chkSearchText===undefined) config.options.chkSearchText=true;
if (config.options.chkSearchTags===undefined) config.options.chkSearchTags=true;
if (config.options.chkSearchFields===undefined) config.options.chkSearchFields=true;
if (config.options.chkSearchTitlesFirst===undefined) config.options.chkSearchTitlesFirst=true;
if (config.options.chkSearchList===undefined) config.options.chkSearchList=true;
if (config.options.chkSearchByDate===undefined) config.options.chkSearchByDate=false;
if (config.options.chkSearchIncremental===undefined) config.options.chkSearchIncremental=true;
if (config.options.chkSearchShadows===undefined) config.options.chkSearchShadows=true;
if (config.macros.search.reportTitle==undefined)
config.macros.search.reportTitle="SearchResults"; // note: not a cookie!
//}}}
//{{{
// searchLink formatter:
// syntax: [search[text to find]] OR [search[text to display|text to find]]
config.formatters.push( {
name: "searchLink",
match: "\\[search\\[",
lookaheadRegExp: /\[search\[(.*?)(?:\|(.*?))?\]\]/mg,
prompt: "search for: '%0'",
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var label=lookaheadMatch[1];
var text=lookaheadMatch[2]||label;
var prompt=this.prompt.format([text]);
var btn=createTiddlyButton(w.output,label,prompt,
function(){story.search(this.getAttribute("searchText"))},"searchLink");
btn.setAttribute("searchText",text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
});
//}}}
//{{{
config.macros.search.searchOptions_onKeyPress = config.macros.search.onKeyPress;
config.macros.search.onKeyPress = function(e)
{
if(!e) var e = window.event;
if (config.options.chkSearchIncremental || e.keyCode==13 || e.keyCode==10 || e.keyCode==27)
config.macros.search.searchOptions_onKeyPress.apply(this,arguments);
}
//}}}
//{{{
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
{
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
var matches = store.search(highlightHack,config.options.chkSearchByDate?"modified":"title","excludeSearch");
if (config.options.chkSearchByDate) matches=matches.reverse(); // most recent changes first
var q = useRegExp ? "/" : "'";
clearMessage();
if (!matches.length) {
if (config.options.chkSearchList) discardSearchResults();
displayMessage(config.macros.search.failureMsg.format([q+text+q]));
} else {
if (config.options.chkSearchList)
reportSearchResults(text,matches);
else {
var titles = []; for(var t=0; t<matches.length; t++) titles.push(matches[t].title);
this.closeAllTiddlers(); story.displayTiddlers(null,titles);
displayMessage(config.macros.search.successMsg.format([matches.length, q+text+q]));
}
}
highlightHack = null;
}
//}}}
//{{{
TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)
{
var candidates = this.reverseLookup("tags",excludeTag,false,sortField);
// scan for matching titles first...
var results = [];
if (config.options.chkSearchTitles) {
for(var t=0; t<candidates.length; t++)
if(candidates[t].title.search(searchRegExp)!=-1)
results.push(candidates[t]);
if (config.options.chkSearchShadows)
for (var t in config.shadowTiddlers)
if ((t.search(searchRegExp)!=-1) && !store.tiddlerExists(t))
results.push((new Tiddler()).assign(t,config.shadowTiddlers[t]));
}
// then scan for matching text, tags, or field data
for(var t=0; t<candidates.length; t++) {
if (config.options.chkSearchText && candidates[t].text.search(searchRegExp)!=-1)
results.pushUnique(candidates[t]);
if (config.options.chkSearchTags && candidates[t].tags.join(" ").search(searchRegExp)!=-1)
results.pushUnique(candidates[t]);
if (config.options.chkSearchFields && store.forEachField!=undefined) // requires TW2.1 or above
store.forEachField(candidates[t],
function(tid,field,val) {
if (val.search(searchRegExp)!=-1) results.pushUnique(candidates[t]);
},
true); // extended fields only
}
// then check for matching text in shadows
if (config.options.chkSearchShadows)
for (var t in config.shadowTiddlers)
if ((config.shadowTiddlers[t].search(searchRegExp)!=-1) && !store.tiddlerExists(t))
results.pushUnique((new Tiddler()).assign(t,config.shadowTiddlers[t]));
// if not 'titles first', or sorting by modification date, re-sort results to so titles, text, tag and field matches are mixed together
if(!sortField) sortField = "title";
var bySortField=function (a,b) {if(a[sortField] == b[sortField]) return(0); else return (a[sortField] < b[sortField]) ? -1 : +1; }
if (!config.options.chkSearchTitlesFirst || config.options.chkSearchByDate) results.sort(bySortField);
return results;
}
//}}}
//{{{
// SearchResults REPORT GENERATOR
// hijack core <<search>> macro to add "report" and "simple inline" output
config.macros.search.SOP_handler=config.macros.search.handler;
config.macros.search.handler = function(place,macroName,params)
{
// if "report", use SearchOptionsPlugin report generator for inline output
if (params[1]&¶ms[1].substr(0,6)=="report") {
var keyword=params[0];
var options=params[1].split("=")[1]; // split "report=option+option+..."
var heading=params[2]?params[2].unescapeLineBreaks():"";
var matches=store.search(new RegExp(keyword.escapeRegExp(),"img"),"title","excludeSearch");
if (matches.length) wikify(heading+window.formatSearchResults(keyword,matches,options),place);
} else if (params[1]) {
var keyword=params[0];
var heading=params[1]?params[1].unescapeLineBreaks():"";
var seperator=params[2]?params[2].unescapeLineBreaks():", ";
var matches=store.search(new RegExp(keyword.escapeRegExp(),"img"),"title","excludeSearch");
if (matches.length) {
var out=[];
for (var m=0; m<matches.length; m++) out.push("[["+matches[m].title+"]]");
wikify(heading+out.join(seperator),place);
}
} else
config.macros.search.SOP_handler.apply(this,arguments);
};
if (!window.reportSearchResults) window.reportSearchResults=function(text,matches)
{
// create/update the tiddler
var title=config.macros.search.reportTitle
var body=window.formatSearchResults(text,matches);
var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch temporary");
store.addTiddler(tiddler);
// render/refresh tiddler
story.closeTiddler(title);
story.displayTiddler(null,title,1);
store.notify(title,true);
}
if (!window.formatSearchResults) window.formatSearchResults=function(text,matches,opt)
{
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
var body="";
if (!opt) var opt="all";
var parts=opt.split("+");
for (var i=0; i<parts.length; i++) { var p=parts[i].toLowerCase();
if (p=="summary"||p=="all")
body+=window.formatSearchResults_summary(text,matches);
if (p=="list"||p=="all")
body+=window.formatSearchResults_list(text,matches);
if (p=="buttons"||p=="all")
body+=window.formatSearchResults_buttons(text,matches);
if (p=="again"||p=="all")
body+=window.formatSearchResults_again(text,matches);
}
return body;
}
if (!window.formatSearchResults_summary) window.formatSearchResults_summary=function(text,matches)
{
// summary: nn tiddlers found matching '...', options used
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
var body="";
body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\n";
body+="^^//searched in:// ";
body+=(config.options.chkSearchTitles?"''titles'' ":"");
body+=(config.options.chkSearchText?"''text'' ":"");
body+=(config.options.chkSearchTags?"''tags'' ":"");
body+=(config.options.chkSearchFields?"''fields'' ":"");
body+=(config.options.chkSearchShadows?"''shadows'' ":"");
if (config.options.chkCaseSensitiveSearch||config.options.chkRegExpSearch) {
body+=" //with options:// ";
body+=(config.options.chkCaseSensitiveSearch?"''case sensitive'' ":"");
body+=(config.options.chkRegExpSearch?"''text patterns'' ":"");
}
body+="^^";
return body;
}
if (!window.formatSearchResults_list) window.formatSearchResults_list=function(text,matches)
{
// bullet list of links to matching tiddlers
var body="\n";
for(var t=0;t<matches.length;t++) {
var date=config.options.chkSearchByDate?(matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" "):"";
body+="* "+date+"[["+matches[t].title+"]]\n";
}
return body;
}
if (!window.formatSearchResults_buttons) window.formatSearchResults_buttons=function(text,matches)
{
// open all matches button
var body="";
var title=config.macros.search.reportTitle;
body+="@@diplay:block;<html><input type=\"button\" href=\"javascript:;\" ";
body+="onclick=\"story.displayTiddlers(null,["
for(var t=0;t<matches.length;t++)
body+="'"+matches[t].title.replace(/\'/mg,"\\'")+"'"+((t<matches.length-1)?", ":"");
body+="],1);\" accesskey=\"O\" value=\"open all matching tiddlers\"></html> ";
// discard search results button
body+="<html><input type=\"button\" href=\"javascript:;\" ";
body+="onclick=\"discardSearchResults()\" value=\"discard "+title+"\"></html>@@";
return body;
}
if (!window.formatSearchResults_again) window.formatSearchResults_again=function(text,matches)
{
var title=config.macros.search.reportTitle
var body="";
// search again
body+="\n!!Search again:\n";
body+="<<search \""+text+"\">>\n";
body+="<<option chkSearchTitles>>titles ";
body+="<<option chkSearchText>>text ";
body+="<<option chkSearchTags>>tags";
body+="<<option chkSearchFields>>fields";
body+="<<option chkSearchShadows>>shadows";
body+="<br>";
body+="<<option chkCaseSensitiveSearch>>case-sensitive ";
body+="<<option chkRegExpSearch>>text patterns";
body+="<<option chkSearchByDate>>sort by date";
body+="<br>";
return body;
}
if (!window.discardSearchResults) window.discardSearchResults=function()
{
// remove the tiddler
story.closeTiddler(config.macros.search.reportTitle);
store.deleteTiddler(config.macros.search.reportTitle);
store.notify(config.macros.search.reportTitle,true);
}
//}}}
/***
|Name|SearchOptionsPluginInfo|
|Source|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#SearchOptionsPluginInfo|
|Version|2.8.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|Documentation for SearchOptionsPlugin|
Extend core search function with additional user-configurable options including selecting which data items to search, enabling/disabling incremental key-by-key searches, and generating a ''list of matching tiddler'' instead of immediately displaying all matches. This plugin also adds syntax for rendering 'search links' within tiddler content to embed one-click searches using pre-defined 'hard-coded' search terms.
!!!!!Search link Syntax
<<<
To insert a 'search link' into tiddler content, you can write:
{{{
[search[text to find]]
}}}
or
{{{
[search[text to display|text to find]]
}}}
Clicking on the resulting search link will trigger the search functionality, just as if the specified 'text to find' had been entered into the standard search input field usually displayed in the document sidebar.
<<<
!!!!!Inline output: search macro syntax
<<<
Alternatively, to embed search results lists directly into your tiddler content, you can use:
{{{
<<search "text" report>> (report is a literal keyword)
<<search "text" "heading" "separator">> (simple inline generator)
}}}
<<<
!!!!!Inline output examples:
<<<
*+++*[<<search "wood">>]>...
<<search "wood">>
===
*+++*[<<search "wood" "/%%/">>]>...
<<search "wood" "/%%/">>
===
*+++*[<<search "wood" "See also: ">>]>...
<<search "wood" "See also: ">>
===
*+++*[<<search "wood" "See also:\n*" "\n*">>]>...
<<search "wood" "See also:\n*" "\n*">>
===
*+++*[<<search "wood" report=list "See also:">>]>...
<<search "wood" report=list "See Also:" >>
===
*+++*[<<search "wood" report>>]>...
<<search "wood" report>>
===
*+++*[<<search "wood" report=>>]>...
<<search "wood" report=>>
===
*+++*[<<search "wood" report=all>>]>...
<<search "wood" report=all>>
===
*+++*[<<search "wood" report=summary+buttons+again+list>>]>...
<<search "wood" report=summary+buttons+again+list>>
===
*+++*[<<search "wood" report=summary+again>>]>...
<<search "wood" report=summary+again>>
===
*+++*[<<search "wood" report=summary>>]>...
<<search "wood" report=summary>>
===
<<<
!!!!!Configuration
<<<
Search in:
<<option chkSearchTitles>> titles <<option chkSearchText>> text <<option chkSearchTags>> tags <<option chkSearchFields>> fields <<option chkSearchShadows>> shadows
>{{{<<option chkSearchTitles>> <<option chkSearchText>> <<option chkSearchTags>>}}}
>{{{<<option chkSearchFields>> <<option chkSearchShadows>>}}}
<<option chkSearchList>> Show list of matches in [[SearchResults]]
>{{{<<option chkSearchList>>}}}
<<option chkSearchIncremental>> Incremental (key-by-key) searching
>{{{<<option chkSearchIncremental>>}}}
<<option chkSearchTitlesFirst>> Show title matches first
>{{{<<option chkSearchTitlesFirst>>}}}
<<option chkSearchByDate>> Sort matching tiddlers by date
>{{{<<option chkSearchByDate>>}}}
<<<
!!!!!Revisions
<<<
2008.08.12 [2.8.2] change default for chkSearchByDate back to FALSE, and adjusted "list" and "again" output formats (minor tweaks requested by PhilWhitehouse for use on TiddlyWiki.com)
2008.08.11 [2.8.1] changed defaults for chkSearchTitlesFirst, chkSearchList and chkSearchShadows to TRUE to enable enhanced search results output as soon as plugin is installed.
2008.06.21 [2.8.0] added extended syntax for {{{<<search "text" report heading>> and <<search "text" "heading" "seperator">>}}}
2008.05.03 [2.7.1] in searchLink formatter handler(), use separate setAttribute() call instead of passing attribs to createTiddlyButton(). Avoids conflict with errant code in TiddlerNotesPlugin (v2.1 26/10/07)
2008.04.29 [2.7.0] added searchLink formatter (syntax: {{{[search[text]]}}} or {{{[search[display|text]]}}})
2008.04.08 [2.6.2] don't automatically add options to AdvancedOptions shadow tiddler
2007.02.17 [2.6.1] added redefinition of config.macros.search.onKeyPress() to restore check to bypass key-by-key searching (i.e., when chkSearchIncremental==false), which had been unintentionally removed with v2.6.0
2007.02.13 [2.6.0] remove redefinition of config.macros.search.handler since core now includes handling for ENTER key.
2007.02.08 [2.5.1] include 'temporary' tag when creating SearchResults (for use with TemporaryTiddlersPlugin)
2007.01.29 [2.5.0] added support for "sort results by date". Default is to sort alphabetically (standard). When sorted by dates, most recent changes are shown first
2006.10.10 [2.4.0] added support for "search in tiddler data" (tiddler.fields) Default is to search extended data.
2006.04.06 [2.3.0] added support for "search in shadow tiddlers". Default is *not* to search in the shadows (i.e. standard TW behavior). Note: if a shadow tiddler has a 'real' counterpart, only the real tiddler is searched, since the shadow is inaccessible for viewing/editing.
2006.02.03 [2.2.1] rewrite timeout clearing code and blank search text handling to match 2.0.4 core release changes. note that core no longer permits "blank=all" searches, so neither does this plugin. To search for all, use "." with text patterns enabled.
2006.02.02 [2.2.0] in search.handler(), KeyHandler() function clears 'left over' timeout when search input is < 3 chars. Prevents searching on shorter text when shortened by rapid backspaces (<500msec)
2006.02.01 [2.1.9] in Story.prototype.search(), correct inverted logic for using/not using regular expressions when searching
also, blank search text now presents "No search text. Continue anyway?" confirm() message box, so search on blank can still be processed if desired by user.
2006.02.01 [2.1.8] in doSearch(), added alert/return if search text is blank
2006.01.20 [2.1.7] fixed setting of config.macros.search.reportTitle so that Tweaks can override it.
2006.01.19 [2.1.6] improved SearchResults formatting, added a "search again" form to the report (based on a suggestion from MorrisGray)
define results report title using config.macros.search.reportTitle instead of hard-coding the tiddler title
2006.01.18 [2.1.5] Created separate functions for reportSearchResults(text,matches) and discardSearchResults(), so that other developers can create alternative report generators.
2006.01.17 [2.1.4] Use regExp.search() instead of regExp.test() to scan for matches. Correctd the problem where only half the matching tiddlers (the odd-numbered ones) were being reported.
2006.01.15 [2.1.3] Added information (date/time, username, search options used) to SearchResults output
2006.01.10 [2.1.2] use displayTiddlers() to render matched tiddlers. This lets you display multiple matching tiddlers, even if SinglePageModePlugin is enabled.
2006.01.08 [2.1.1] corrected invalid variable reference, "txt.value" to "text" in story.search()
2006.01.08 [2.1.0] re-write to match new store.search(), store.search.handler() and story.search() functions.
2005.12.30 [2.0.0] Upgraded to TW2.0. When rendering SearchResults tiddler, closeTiddler() first to ensure display is refreshed.
2005.12.26 [1.4.0] added option to search for matching text in tiddler tags
2005.12.21 [1.3.7] use \\ to 'escape' single quotes in tiddler titles when generating "Open all matching tiddlers" link. Also, added access key: "O", to trigger "open all" link. Based on a suggestion by UdoBorkowski.
2005.12.18 [1.3.6] call displayMessage() AFTER showing matching tiddlers so message is not cleared too soon
2005.12.17 [1.3.5] if no matches found, just display message and delete any existing SearchResults tiddler.
2005.12.17 [1.3.4] use {/%%/{/%%/{ and }/%%/}/%%/} to 'escape' display text in SearchResults tiddler to ensure that formatting contained in search string is not rendered. Based on a suggestion by UdoBorkowski.
2005.12.14 [1.3.3] tag SearchResults tiddler with 'excludeSearch' so it won't list itself in subsequent searches. Based on a suggestion by UdoBorkowski.
2005.12.14 [1.3.2] added "open all matching tiddlers..." link to search results output. Based on a suggestion by UdoBorkowski.
2005.12.10 [1.3.1] added "discard search results" link to end of search list tiddler output for quick self-removal of 'SearchResults' tiddler.
2005.12.01 [1.3.0] added chkSearchIncremental to enable/disable 'incremental' searching (i.e., search after each keystroke) (default is ENABLED).
added handling for Enter key so it can be used to start a search. Based on a suggestion by LyallPearce
2005.11.25 [1.2.1] renamed from SearchTitleOrTextPlugin to SearchOptionsPlugin
2005.11.25 [1.2.0] added chkSearchList option. Based on a suggestion by RodneyGomes
2005.10.19 [1.1.0] added chkSearchTitlesFirst option. Based on a suggestion by ChristianHauck
2005.10.18 [1.0.0] Initial Release. Based on a suggestion by LyallPearce.
<<<
''2 tiddlers found matching '{{{Audio-Mac}}}'''
^^//searched in:// ''titles'' ''text'' ''tags'' ''fields'' ''shadows'' ^^
* [[MIDI Dictionary]]
* [[MarkupPreHead]]
@@diplay:block;<html><input type="button" href="javascript:;" onclick="story.displayTiddlers(null,['MIDI Dictionary', 'MarkupPreHead'],1);" accesskey="O" value="open all matching tiddlers"></html> <html><input type="button" href="javascript:;" onclick="discardSearchResults()" value="discard SearchResults"></html>@@
!!Search again:
<<search "Audio-Mac">>
<<option chkSearchTitles>>titles <<option chkSearchText>>text <<option chkSearchTags>>tags<<option chkSearchFields>>fields<<option chkSearchShadows>>shadows<br><<option chkCaseSensitiveSearch>>case-sensitive <<option chkRegExpSearch>>text patterns<<option chkSearchByDate>>sort by date<br>
<<tiddler HideTiddlerBackground>><<tiddler HideTiddlerTags>>/%
%/<<tabs "catalogTab"
"summary" "summary of tiddler statistics" TabSummary
"tags" "overview of document tags using grid and cloud displays" TabTagInfo
"packages" "groups of tiddlers, tagged for quick import into your documents" TabPackages
"plugins" "programmed add-ons and extensions to TiddlyWiki standard features" TabPlugins
"scripts" "inline javascript" TabScripts
"templates" "page and tiddler layout definitions" TabTemplates
"themes" "stylesheets for different look-and-feel 'themes'" TabThemes
"bookmarks" "favorite websites embedded in tiddlers" TabBookmarks
>><script>
var tabset=place.lastChild.firstChild;
if (!tabset || !hasClass(tabset,"tabset")) return; // no tabset... we're done.
tabset.style.paddingTop=".5em"; // tweak padding
return;
var tabs=tabset.getElementsByTagName("A");
for (var t=0; t<tabs.length; t++) // dim tabs (except selected one)
if (hasClass(tabs[t],"tabUnselected"))
addClass(tabs[t],"mouseover");
</script>
<<showUpdates onlyTag:RecentUpdates maxEntries:8>>
{{{<<showUpdates onlyTag:RecentUpdates maxEntries:8>>}}}
----
<<showUpdates onlyTag:RecentUpdates write:'(index==0? countLine + "\n{{blog{\n":"")+(index<8?"!!![["+tiddler.title+"]]@@color:#999;font-size:70%;" +tiddler.modified.formatString(" - DD/MM/YY")+"@@\n" +"{{excerpt{\n"+tiddler.text.substr(0,100)+"...\n[[read more...|"+tiddler.title+"]]\n}}}\n":"")+(index==count-1?"}}}":"")' >>
{{{
<<showUpdates
onlyTag:RecentUpdates
write:
'(index==0? countLine + "\n{{blog{\n":"")+
(index<8?"!!![["+tiddler.title+"]]@@color:#999;font-size:70%;" +tiddler.modified.formatString(" - DD/MM/YY")+"@@\n" +"{{excerpt{\n"+tiddler.text.substr(0,100)+"...\n[[read more...|"+tiddler.title+"]]\n}}}\n":"")+
(index==count-1?"}}}":"")'
>>
}}}
this one requires the following css in your StyleSheet:
//{{{
.blog h2, .blog h3, .blog h4{
margin:0;
padding:0;
border-bottom:none;
}
.blog {margin-left:1.5em;}
.blog .excerpt {
margin:0;
margin-top:0.3em;
padding: 0;
margin-left:1em;
padding-left:1em;
font-size:90%;
border-left:1px solid #ddd;
}
//}}}
{{button{goto}}}
<<gotoTiddler width:11em>><<search>>
<<popup commands [[<<tiddler Commands$))]]>>
<<tabs txtMainTab "Lasts" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>
music composer – film, theatre, scenic...
<<popup Sekvencery [[<<tiddler Sekvencery$))]]>>
<<popup Editory [[<<tiddler Editory$))]]>>
<<popup Měřící [[<<tiddler Měřící$))]]>>
----
<<popup Ostatní [[<<tiddler Ostatní$))]]>>
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};
//--
//-- Sparklines
//--
config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
var data = [];
var min = 0;
var max = 0;
var v;
for(var t=0; t<params.length; t++) {
v = parseInt(params[t]);
if(v < min)
min = v;
if(v > max)
max = v;
data.push(v);
}
if(data.length < 1)
return;
var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
box.title = data.join(",");
var w = box.offsetWidth;
var h = box.offsetHeight;
box.style.paddingRight = (data.length * 2 - w) + "px";
box.style.position = "relative";
for(var d=0; d<data.length; d++) {
var tick = document.createElement("img");
tick.border = 0;
tick.className = "sparktick";
tick.style.position = "absolute";
tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
tick.style.left = d*2 + "px";
tick.style.width = "2px";
v = Math.floor(((data[d] - min)/(max-min)) * h);
tick.style.top = (h-v) + "px";
tick.style.height = v + "px";
box.appendChild(tick);
}
};
}
//}}}
/***
''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''
|Name|SplashScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#SplashScreenPlugin|
|Version|0.21 |
|Requires|~TW2.08+|
!Description:
Provides a simple splash screen that is visible while the TW is loading.
!Installation
Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.
!Customizing
Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.
!History
* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
* 26-06-06 : version 0.2, first release
!Code
***/
//{{{
var old_lewcid_splash_restart=restart;
restart = function()
{ if (document.getElementById("SplashScreen"))
document.getElementById("SplashScreen").style.display = "none";
if (document.getElementById("contentWrapper"))
document.getElementById("contentWrapper").style.display = "block";
old_lewcid_splash_restart();
if (splashScreenInstall)
{if(config.options.chkAutoSave)
{saveChanges();}
displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
}
}
var oldText = store.getTiddlerText("MarkupPreHead");
if (oldText.indexOf("SplashScreen")==-1)
{var siteTitle = store.getTiddlerText("SiteTitle");
var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
if (! store.tiddlerExists("MarkupPreHead"))
{var myTiddler = store.createTiddler("MarkupPreHead");}
else
{var myTiddler = store.getTiddler("MarkupPreHead");}
myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
store.setDirty(true);
var splashScreenInstall = true;
}
//}}}
Updated to hide the contentWrapper while the SplashScreen is displayed.
Coming Soon: easier editing of the SplashScreen.
Get it here: SplashScreenPlugin.
/*{{{*/
#sidebar {position:absolute; right:13px; width:17em; font-size:.9em;}
#sidebarOptions .sliderPanel a {display:block; padding : 0.2em 0}
#sidebarOptions .sliderPanel .sliderPanel a {display:inline}
#sidebarOptions .button {margin:0em 0.2em;padding:0.2em 0.3em}
#tiddlersBar .tab {-moz-border-radius : 0.4em 0.4em 0 0}
.tiddler {-moz-border-radius : 0.4em; padding-bottom : 1em}
.popup {padding:0.4em;}
#nestedpopup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup a, .popup a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
#displayArea {
margin:1em 1em 1em 20em;
width:735px;
}
/*}}}*/
/***
|Name|StyleSheetAdjustments|
|Source|http://www.TiddlyTools.com/#StyleSheetAdjustments|
|Version||
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|CSS|
|Requires||
|Overrides||
|Description|adjust TiddlyWiki default shadow stylesheets definitions|
***/
[[StyleSheetPlugins]] /* include adjustments to plugin-supplied definitions */
[[StyleSheetShortcuts]] /* include formatting "shortcut" definitions */
[[Jash.css]] /* Javascript Shell (jash) Styles */
/***
These 'style tweaks' can be easily included in other stylesheet tiddler so they can share a baseline look-and-feel that can then be customized to create a wide variety of 'flavors'.
/***
!body /%==================================================%/
IE needs explicit "position:static" declaration (fixes 'partial background display bug')
***/
/*{{{*/
body { font-family: Verdana,Arial,Helvetica; position:static; }
/*}}}*/
/***
!backstage /%==================================================%/
fix for bug #347/#349, wherein backstageCloak covers backstagePanel whenever fixed elements are present
***/
/*{{{*/
#backstageCloak { z-index:49; }
#backstagePanel { margin:0em 0.5em 0em 0.5em; }
#backstageButton a:hover
{background-color:transparent !important;}
/*}}}*/
/***
!common colors /%==================================================%/
***/
/*{{{*/
/* these seem to have been omitted from the core defaults for link styles */
a { color:#014; }
a:hover { color:#def; }
/*}}}*/
/***
!HTML forms /%==================================================%/
***/
/*{{{*/
/* eliminate whitespace before/after form controls */
form { margin:0;padding:0; }
/*}}}*/
/***
!basic styling /%==================================================%/
***/
/*{{{*/
/* reduce whitespace before/after horizontal rule */
hr { margin:2px 0 1px 0;padding:0; }
/*}}}*/
/***
!header and titles /%==================================================%/
IE needs explicit "position:static" declaration (fixes 'background display hides text bug')
***/
/*{{{*/
.header
{ background:transparent; padding:.2em 1em; position:static; margin-bottom:.5em; }
.headerShadow, .headerForeground
{ padding:.5em; }
.header a, .header .button, .header .tiddlyLinkExisting, .header .tiddlyLinkNonExisting
{ font-weight: normal; }
.header .externalLink,
.siteSubtitle a, .siteSubtitle .button, .siteSubtitle .tiddlyLinkExisting, .siteSubtitle .tiddlyLinkNonExisting
{ text-decoration:none; }
.header table
{ border-collapse: collapse !important; }
/*}}}*/
/***
!displayArea /%==================================================%/
***/
/*{{{*/
#displayArea
{ margin:0em 17em 0em 11em; }
/*}}}*/
/***
!popups /%==================================================%/
white-space:nowrap prevents items from wrapping if popup is near right edge of window
z-index:1000 makes sure popup is above EVERYTHING else
***/
/*{{{*/
.popup
{ white-space: nowrap; z-index:1000; color: #000; background: #ffe; border: 1px solid #000;
-moz-border-radius-topright: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; }
.popup a, .popup .button, .popup .tiddlyLinkExisting, .popup .tiddlyLinkNonExisting
{ font-weight: normal; font-style: normal; }
.popup hr
{ color: #000; background: #ddd; border: 0; }
.popup li.disabled
{ color: #999; }
.popup li a, .popup li a:visited
{ color: #300; padding:1px; }
.popup li a:hover
{ background: #006; color: #fff !important;}
/*}}}*/
/***
!messageArea /%==================================================%/
***/
/*{{{*/
#messageArea
{ font-size:90%; -moz-border-radius:1em; background:#eee; }
/*}}}*/
/***
!main menu (left sidebar) /%==================================================%/
***/
/*{{{*/
#mainMenu
{ z-index:1; width:9em; text-align:left; margin:0; margin-left:1.5em; padding:0; clear:both; }
*[id="mainMenu"] /* moz browsers only */
{ width:auto !important; }
/*}}}*/
/***
!sidebar (right sidebar) /%==================================================%/
***/
/*{{{*/
#sidebar
{ width:18em; margin-right:1em; clear:both; }
#sidebarTabs .tab
{ font-size:90%; -moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em; }
#sidebarTabs .tabContents
{ background:transparent; border:1px solid #999; padding:.5em; height:auto; overflow:auto; width:92.5%; }
#sidebarTabs .tabContents .tabContents
{ background:transparent; border:1px solid #999; padding:.5em; height:auto; }
#sidebarOptions input[type="text"]
{ font-size:8pt; }
}
*/
/*}}}*/
/***
!tabs /%==================================================%/
***/
/*{{{*/
.tabset
{ padding: 0.2em 0 0 0; }
.tab
{ padding:0 1px 0 1px; }
.viewer .tab
{ padding:0 .5em 0 .5em; }
.tabSelected
{ border: 1px solid; border-bottom: 0px !important; margin-bottom:-2px !important; -moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em;}
.tabUnselected
{ border: 1px solid #999; border-bottom:0px; -moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em;}
.tabContents
{ border: 1px solid; -moz-border-radius:1em; padding: 1em; }
/*}}}*/
/***
!tiddler display elements /%==================================================%/
***/
/*{{{*/
.tiddler
{ padding: 0 1em 1em 1em; }
.button, .button:hover, .button:active,
.viewer .button, .viewer .button:hover, .viewer .button:active
{ background:transparent; border:0; }
.toolbar
{ float:right; display:inline; padding-bottom:0; visibility:hidden; }
.selected .toolbar
{ visibility:visible; }
.toolbar .floatingPanel
{ visibility:visible !important; } /* make sure floating panels from toolbars don't disappear on mouseout */
.toolbar .button, .toolbar a
{ border:1px solid transparent; background:transparent; margin:0px 1px; padding:0px .2em; -moz-border-radius:.5em; }
.toolbar
{color:[[ColorPalette::TertiaryLight]];}
.toolbar a
{color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar
{color:[[ColorPalette::Foreground]];}
.selected .toolbar, .selected .toolbar .button, .selected .toolbar a
{ color:#006; }
.toolbar .button:hover, .toolbar a:hover
{ border:1px solid #69c !important; background:#006 !important; color:#fff !important; }
.shadow .tagging, .shadow .tagged
{ display:none; }
.tagging, .tagged
{ background-color: #ccc; border: 1px solid; }
.selected .tagging, .selected .tagged
{ background-color:#eee; border: 1px solid #999; }
.tagging, .tagged
{ -moz-border-radius:1em; }
.subtitle
{ font-size:90%; }
.shadow input, .shadow textarea, .shadow button, .shadow checkbox, .shadow radio, .shadow select
{ font-size:90%; }
.shadow input, .shadow textarea, .shadow button, .shadow checkbox, .shadow radio, .shadow select
{ font-size:90%; }
.editor input
{ font-size: 8pt;}
.editor textarea
{ font-size: 8pt; font-family:monospace; }
.editor select
{ font-size: 8pt; border:1px solid; }
.title
{ font-size: 12pt; line-height:120%; }
.viewer
{ font-size: 9pt; padding: 0.7em; text-align:justify; }
.viewer pre, .viewer code, .viewer blockquote
{ font-size:8pt; text-align:left; }
.viewer pre
{ background:#ffe; border:1px solid; }
.viewer table, .viewer table tr, .viewer table td
{ border:1px solid; }
.viewer hr {
margin: 1px; padding:1px;
border:0;
border-top: solid 1px #666;
color: #666;
}
.viewer blockquote {
line-height: 1.5em;
padding-left: 1em;
margin-left: 1em;
border-left: 1px dotted;
}
/*}}}*/
/***
|Name|StyleSheetPlugins|
|Source|http://www.TiddlyTools.com/#StyleSheetPlugins|
|Version||
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|CSS|
|Requires||
|Overrides||
|Description|definitions for plugin-specific ID's and classes|
The following CSS declarations modify default style classes defined by various plugins and scripts, and/or used in customized Page/View/Edit templates
These 'style tweaks' can be easily included in other stylesheet tiddler so they can share a baseline look-and-feel that can then be customized to create a wide variety of 'flavors'.
/***
!PageTemplate - siteMenu
***/
/*{{{*/
.siteMenu
{ background:transparent; padding:.5em; padding-top:0; margin:0; }
.siteMenu a, .siteMenu .button, .siteMenu .tiddlyLinkExisting, .siteMenu .tiddlyLinkNonExisting
{ font-weight: normal; font-style: normal; }
/*** LEAVE THESE OUT FOR NOW
.siteMenu .button, .siteMenu a
{ border:1px solid transparent; background:transparent; margin:0px; padding:0px 1px; -moz-border-radius:.5em; }
.siteMenu .button:hover, .siteMenu a:hover
{ border:1px solid #69c; background:#006; color:#fff; }
***/
/*}}}*/
/***
!PageTemplate - storyMenu
***/
/*{{{*/
.storyMenu
{ display:block; margin:0em 1em .5em 1em; }
.storyMenu a, .storyMenu .button, .storyMenu .tiddlyLinkExisting, .storyMenu .tiddlyLinkNonExisting
{ font-weight: normal; font-style: normal; text-decoration:none; }
/*}}}*/
/***
!NestedSlidersPlugin
***/
/*{{{*/
.floatingPanel
{ z-index:700; padding:1em; margin:0em; border:1px solid; -moz-border-radius:1em; font-size:8pt; text-align:left; }
.floatingPanel hr
{ margin:2px 0 1px 0; padding:0; }
#sidebarOptions .sliderPanel
{ margin:0; padding:0; font-size:1em; background:transparent; }
#sidebarOptions .sliderPanel a
{ font-weight:normal; }
#sidebarOptions .sliderPanel blockquote
{ margin:0;padding:0;margin-left:1em; border-left:1px dotted; padding-left:1em }
.selected .floatingPanel .button,
.selected .floatingPanel a:link,
.selected .floatingPanel a:hover,
.selected .floatingPanel a:visited,
.floatingPanel .button,
.floatingPanel a:link,
.floatingPanel a:hover,
.floatingPanel a:visited
{ color:[[ColorPalette::PrimaryDark]] !important; }
/*}}}*/
/***
!CheckboxPlugin
***/
/*{{{*/
input[type="Checkbox"]
{ margin-top:2px;margin-bottom:2px; }
/*}}}*/
/***
!BreadcrumbsPlugin
***/
/*{{{*/
/* smaller size for bread crumbs (see BreadcrumbsPlugin) */
#breadCrumbs
{ display:none; margin:0em 1em; padding-bottom:.5em; font-size:7pt; } /* display:block is set by plugin when crumbs are in use */
/*}}}*/
/***
!TableOfContentsPlugin
***/
/*{{{*/
#sidebarTabs .tabContents *[class="TOCList"] /* MOZ ONLY */
{ background-color: transparent; border-color:transparent !important; }
/*}}}*/
/***
!AttachFilePlugin
***/
/*{{{*/
#sidebar .attachPanel
{ right:115%; top:3em; text-align:left; }
/*}}}*/
/***
!ImportTiddlersPlugin
***/
/*{{{*/
#sidebar #importPanel
{ right:115%; top:6em; text-align:left; }
/*}}}*/
/***
!ExportTiddlersPlugin
***/
/*{{{*/
#sidebar #exportPanel
{ right:115%; top:9em; text-align:left; }
/*}}}*/
/***
!QuoteOfTheDayPlugin
***/
/*{{{*/
.QOTD
{ color:inherit !important; background:inherit !important; }
/*}}}*/
/***
!TableSorterPlugin
***/
/*{{{*/
.sortedCol
{ color:inherit !important; background:inherit !important; }
/*}}}*/
/***
|Name|StyleSheetShortcuts|
|Source|http://www.TiddlyTools.com/#StyleSheetShortcuts|
|Version||
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|CSS|
|Requires||
|Overrides||
|Description|'convenience' classes for common formatting, alignment, boxes, tables, etc.|
These 'style tweaks' can be easily included in other stylesheet tiddler so they can share a baseline look-and-feel that can then be customized to create a wide variety of 'flavors'.
***/
/*{{{*/
/* text alignments */
.left
{ display:block;text-align:left; }
.center
{ display:block;text-align:center; }
.right
{ display:block;text-align:right; }
.justify
{ display:block;text-align:justify; }
.indent
{ display:block;margin:0;padding:0;border:0;margin-left:2em; }
.floatleft
{ float:left; }
.floatright
{ float:right; }
.valignTop, .valignTop table, .valignTop tbody, .valignTop th, .valignTop tr, .valignTop td
{ vertical-align:top; }
.valignBottom, .valignBottom table, .valignBottom tbody, .valignBottom th, .valignBottom tr, .valignBottom td
{ vertical-align:bottom; }
.clear
{ clear:both; }
.wrap
{ white-space:normal; }
.nowrap
{ white-space:nowrap; }
.hidden
{ display:none; }
.show
{ display:inline !important; }
.span
{ display:span; }
.block
{ display:block; }
.relative
{ position:relative; }
.absolute
{ position:absolute; }
/* font sizes */
.big
{ font-size:14pt;line-height:120% }
.medium
{ font-size:12pt;line-height:120% }
.normal
{ font-size:9pt;line-height:120% }
.small
{ font-size:8pt;line-height:120% }
.fine
{ font-size:7pt;line-height:120% }
.tiny
{ font-size:6pt;line-height:120% }
.larger
{ font-size:120%; }
.smaller
{ font-size:80%; }
/* font styles */
.bold
{ font-weight:bold; }
.italic
{ font-style:italic; }
.underline
{ text-decoration:underline; }
/* plain list items (no bullets or indent) */
.nobullets li { list-style-type: none; margin-left:-2em; }
/* multi-column tiddler content (not supported in Internet Explorer) */
.twocolumns { display:block;
-moz-column-count:2; -moz-column-gap:1em; -moz-column-width:50%; /* FireFox */
-webkit-column-count:2; -webkit-column-gap:1em; -webkit-column-width:50%; /* Safari */
column-count:2; column-gap:1em; column-width:50%; /* Opera */
}
.threecolumns { display:block;
-moz-column-count:3; -moz-column-gap:1em; -moz-column-width:33%; /* FireFox */
-webkit-column-count:3; -webkit-column-gap:1em; -webkit-column-width:33%; /* Safari */
column-count:3; column-gap:1em; column-width:33%; /* Opera */
}
.fourcolumns { display:block;
-moz-column-count:4; -moz-column-gap:1em; -moz-column-width:25%; /* FireFox */
-webkit-column-count:4; -webkit-column-gap:1em; -webkit-column-width:25%; /* Safari */
column-count:4; column-gap:1em; column-width:25%; /* Opera */
}
/* show/hide browser-specific content for InternetExplorer vs. non-IE ("moz") browsers */
*[class="ieOnly"]
{ display:none; } /* hide in moz (uses CSS selector) */
* html .mozOnly, *:first-child+html .mozOnly
{ display: none; } /* hide in IE (uses IE6/IE7 CSS hacks) */
/* borderless tables */
.borderless, .borderless table, .borderless td, .borderless tr, .borderless th, .borderless tbody
{ border:0 !important; margin:0 !important; padding:0 !important; }
.widetable, .widetable table
{ width:100%; }
/* thumbnail images (fixed-sized scaled images) */
.thumbnail img { height:5em !important; }
/* stretchable images (auto-size to fit tiddler) */
.stretch img { width:95%; }
/* grouped content */
.outline
{ display:block; padding:1em; -moz-border-radius:1em; border:1px solid; }
.menubox
{ display:block; padding:1em; -moz-border-radius:1em; border:1px solid; background:#fff; color:#000; }
.menubox .button, .menubox .tiddlyLinkExisting, .menubox .tiddlyLinkNonExisting
{ color:#009 !important; }
.groupbox
{ display:block; padding:1em; -moz-border-radius:1em; border:1px solid; background:#ffe; color:#000; }
.groupbox a, .groupbox .button, .groupbox .tiddlyLinkExisting, .groupbox .tiddlyLinkNonExisting
{ color:#009 !important; }
.groupbox code
{ color:#333 !important; }
.borderleft
{ margin:0;padding:0;border:0;margin-left:1em; border-left:1px dotted; padding-left:.5em; }
.borderright
{ margin:0;padding:0;border:0;margin-right:1em; border-right:1px dotted; padding-right:.5em; }
.borderbottom
{ margin:0;padding:1px 0;border:0;border-bottom:1px dotted; margin-bottom:1px; padding-bottom:1px; }
.bordertop
{ margin:0;padding:0;border:0;border-top:1px dotted; margin-top:1px; padding-top:1px; }
/* compact form */
.smallform
{ white-space:nowrap; }
.smallform input, .smallform textarea, .smallform button, .smallform checkbox, .smallform radio, .smallform select
{ font-size:8pt; }
/* stretchable edit fields and textareas (auto-size to fit tiddler) */
.stretch input { width:99%; }
.stretch textarea { width:99%; }
/* compact input fields (limited to a few characters for entering percentages and other small values) */
.onechar input { width:1em; }
.twochar input { width:2em; }
.threechar input { width:3em; }
.fourchar input { width:4em; }
.fivechar input { width:5em; }
/* text colors */
.green { color:#0c0 !important }
.red { color:#f66 !important }
.blue { color:#99f !important }
.gray { color:#999 !important }
/* rollover highlighting */
.mouseover
{color:[[ColorPalette::TertiaryLight]] !important;}
.mouseover a
{color:[[ColorPalette::TertiaryLight]] !important;}
.selected .mouseover
{color:[[ColorPalette::Foreground]] !important;}
.selected .mouseover .button, .selected .mouseover a
{color:[[ColorPalette::PrimaryDark]] !important;}
/* rollover zoom text */
.zoomover
{ font-size:80% !important; }
.selected .zoomover
{ font-size:100% !important; }
/*}}}*/
/%
|Name|StyleTester|
|Source|http://www.TiddlyTools.com/#StyleTester|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|TidIDE: define and apply CSS "on the fly"|
%/<<tiddler HideTiddlerTags>>{{smallform{<script>
var elems=document.getElementsByTagName("*");
var out='<html><form>';
out+='<select size=1 name=elems style="width:80%" ';
out+=' onchange="this.form.css.value=\'\'; if (!this.value.length) return;';
out+=' this.form.apply.disabled=false;';
out+=' this.form.done.disabled=false; this.form.css.style.display=\'block\';';
out+=' var e=document.getElementById(this.value);';
out+=' this.form.css.value=\'#%0 { %1 }\'.format([this.value,e.style.cssText]);">';
out+='<option value=\'\'>select an element ID...</option>';
for (var i=0;i<elems.length;i++) { if (elems[i].id.length) out+='<option value="%0">ID: %0</option>'.format([elems[i].id]); }
out+='</select>';
out+='<input type=button name=apply style="width:10%" value="apply" disabled onclick="setStylesheet(this.form.css.value,\'testStyles\')">';
out+='<input type=button name=done style="width:10%" disabled value="done" onclick="this.form.css.value=\'\'; this.form.css.style.display=\'none\'; this.form.elems.selectedIndex=0; this.form.apply.disabled=this.disabled=true"><br>';
out+='<textarea name=css rows=15 style="width:100%;height:15em;display:none"';
out+=' onkeyup="if (event.ctrlKey && event.keyCode==13) this.form.apply.click()"></textarea>';
out+='</form></html>';
return out;
</script>}}}
''Below, you can see an additional //source// column and an additional //reset source// button.''
(reopen this tiddler to see changes after reseting source)
<<sync>>
/***
|''Name:''|SyncFromSourcePlugin|
|''Description:''|Synchronizes plugins from their original source (issued from plugin info) instead of imported url. So, plugins can be imported from any existing tiddlywiki and still be synchronized with their original source.|
|''Version:''|1.0.0|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 1.5; InternetExplorer 6.0|
!Usage
#import the plugin, save and reload.
#a new column (source) is available in ''sync task'' from the ''backstage button''. If the plugin's source mismatches the plugin server.host (the place from which is was last imported), the source value is displayed.
#a new button is also available : ''reset source''. Click on this button applies plugin's ''source'' as server.host for the checked lines.
Look at this [[example|SyncFromSourceDemo]] on plugin [[homepage|http://visualtw.ouvaton.org/VisualTW.html]].
!Patch required for TiddlyWiki 2.3.0
A bug in TW2.3.0 requires [[SyncPatch]].
!Code
***/
//{{{
config.macros.sync.getSyncableTiddlersWithoutSource = config.macros.sync.getSyncableTiddlersWithoutSource ? config.macros.sync.getSyncableTiddlersWithoutSource : config.macros.sync.getSyncableTiddlers;
config.macros.sync.startSyncWithoutSource = config.macros.sync.startSyncWithoutSource ? config.macros.sync.startSyncWithoutSource : config.macros.sync.startSync;
config.macros.sync.getSyncableTiddlers = function(){
var syncs = config.macros.sync.getSyncableTiddlersWithoutSource();
for(var cpt=0;cpt<syncs.length;cpt++){
var s= getPluginInfo(syncs[cpt].tiddler).Source;
if (s) {
var source = FileAdaptor.minHostName(s);
source = source.replace(/#[^#]*$/,"").replace(/\/*$/,"");
syncs[cpt].source = (source==syncs[cpt].tiddler.fields["server.host"]) ? "": source;
}
else syncs[cpt].source = "";
}
return syncs;
}
config.macros.sync.startSync = function(place) {
config.macros.sync.startSyncWithoutSource(place);
var w = new Wizard(place.getElementsByTagName("form")[0]);
w.setButtons([
{caption: this.syncLabel, tooltip: this.syncPrompt, onClick: this.doSync},
{caption: this.syncSourceLabel, tooltip: this.syncSourcePrompt, onClick: this.doSyncSource}
]);
}
merge(config.macros.sync,{
syncSourceLabel : "reset source",
syncSourcePrompt : "reset synchronization to plugin source, if available"
})
config.macros.sync.doSyncSource = function(e)
{
var rowNames = ListView.getSelectedRows(currSync.listView);
for(var t=0; t<currSync.syncList.length; t++) {
var si = currSync.syncList[t];
if((rowNames.indexOf(si.title) != -1)&&si.source) {
si.tiddler.fields["server.host"]=si.source;
si.tiddler.fields["server.type"]="file";
store.setDirty(true);
}
}
backstage.switchTab(null);
return false;
};
config.macros.sync.listViewTemplate.columns.push({name: 'Source', field: 'source', title: "Source", type: 'Link'});
//}}}
/***
Corrects a bug in TiddlyWiki 2.3.0
***/
//{{{
FileAdaptor.getTiddlerComplete = function(context,userParams)
{
var t = context.adaptor.store.fetchTiddler(context.title);
t.fields['server.type'] = FileAdaptor.serverType;
t.fields['server.host'] = FileAdaptor.minHostName(context.host);
t.fields['server.page.revision'] = t.modified.convertToYYYYMMDDHHMM();
context.tiddler = t;
context.status = true;
if(context.allowSynchronous) {
context.isSynchronous = true;
context.callback(context,userParams);
} else {
window.setTimeout(function() {context.callback(context,userParams);},10);
}
return true;
};
//}}}
I'm working for University, where is creating Synthesis of czech speech, like sound engineer.
/***
|''Name:''|TableSortingPlugin|
|''Description:''|Dynamically sort tables by clicking on column headers|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TableSortingPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.02|
|''Date:''|25-01-2008|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
* Make sure your table has a header row
** {{{|Name|Phone Number|Address|h}}}<br> Note the /h/ that denote a header row
* Give the table a class of 'sortable'
** {{{
|sortable|k
|Name|Phone Number|Address|h
}}}<br>Note the /k/ that denotes a class name being assigned to the table.
* To disallow sorting by a column, place {{{<<nosort>>}}} in it's header
* To automatically sort a table by a column, place {{{<<autosort>>}}} in the header for that column
** Or to sort automatically but in reverse order, use {{{<<autosort reverse>>}}}
!!Example:
|sortable|k
|Name |Salary |Extension |Performance |File Size |Start date |h
|ZBloggs, Fred |$12000.00 |1353 |+1.2 |74.2Kb |Aug 19, 2003 21:34:00 |
|ABloggs, Fred |$12000.00 |1353 |1.2 |3350b |09/18/2003 |
|CBloggs, Fred |$12000 |1353 |1.200 |55.2Kb |August 18, 2003 |
|DBloggs, Fred |$12000.00 |1353 |1.2 |2100b |07/18/2003 |
|Bloggs, Fred |$12000.00 |1353 |01.20 |6.156Mb |08/17/2003 05:43 |
|Turvey, Kevin |$191200.00 |2342 |-33 |1b |02/05/1979 |
|Mbogo, Arnold |$32010.12 |2755 |-21.673 |1.2Gb |09/08/1998 |
|Shakespeare, Bill |£122000.00|3211 |6 |33.22Gb |12/11/1961 |
|Shakespeare, Hamlet |£9000 |9005 |-8 |3Gb |01/01/2002 |
|Fitz, Marvin |€3300.30 |5554 |+5 |4Kb |05/22/1995 |
***/
// /%
//!BEGIN-PLUGIN-CODE
config.tableSorting = {
darrow: "\u2193",
uarrow: "\u2191",
getText : function (o) {
var p = o.cells[SORT_INDEX];
return p.innerText || p.textContent || '';
},
sortTable : function (o,rev) {
SORT_INDEX = o.getAttribute("index");
var c = config.tableSorting;
var T = findRelated(o.parentNode,"TABLE");
if(T.tBodies[0].rows.length<=1)
return;
var itm = "";
var i = 0;
while (itm == "" && i < T.tBodies[0].rows.length) {
itm = c.getText(T.tBodies[0].rows[i]).trim();
i++;
}
if (itm == "")
return;
var r = [];
var S = o.getElementsByTagName("span")[0];
c.fn = c.sortAlpha;
if(!isNaN(Date.parse(itm)))
c.fn = c.sortDate;
else if(itm.match(/^[$|£|€|\+|\-]{0,1}\d*\.{0,1}\d+$/))
c.fn = c.sortNumber;
else if(itm.match(/^\d*\.{0,1}\d+[K|M|G]{0,1}b$/))
c.fn = c.sortFile;
for(i=0; i<T.tBodies[0].rows.length; i++) {
r[i]=T.tBodies[0].rows[i];
}
r.sort(c.reSort);
if(S.firstChild.nodeValue==c.darrow || rev) {
r.reverse();
S.firstChild.nodeValue=c.uarrow;
}
else
S.firstChild.nodeValue=c.darrow;
var thead = T.getElementsByTagName('thead')[0];
var headers = thead.rows[thead.rows.length-1].cells;
for(var k=0; k<headers.length; k++) {
if(!hasClass(headers[k],"nosort"))
addClass(headers[k].getElementsByTagName("span")[0],"hidden");
}
removeClass(S,"hidden");
for(i=0; i<r.length; i++) {
T.tBodies[0].appendChild(r[i]);
c.stripe(r[i],i);
for(var j=0; j<r[i].cells.length;j++){
removeClass(r[i].cells[j],"sortedCol");
}
addClass(r[i].cells[SORT_INDEX],"sortedCol");
}
},
stripe : function (e,i){
var cl = ["oddRow","evenRow"];
i&1? cl.reverse() : cl;
removeClass(e,cl[1]);
addClass(e,cl[0]);
},
sortNumber : function(v) {
var x = parseFloat(this.getText(v).replace(/[^0-9.-]/g,''));
return isNaN(x)? 0: x;
},
sortDate : function(v) {
return Date.parse(this.getText(v));
},
sortAlpha : function(v) {
return this.getText(v).toLowerCase();
},
sortFile : function(v) {
var j, q = config.messages.sizeTemplates, s = this.getText(v);
for (var i=0; i<q.length; i++) {
if ((j = s.toLowerCase().indexOf(q[i].template.replace("%0\u00a0","").toLowerCase())) != -1)
return q[i].unit * s.substr(0,j);
}
return parseFloat(s);
},
reSort : function(a,b){
var c = config.tableSorting;
var aa = c.fn(a);
var bb = c.fn(b);
return ((aa==bb)? 0 : ((aa<bb)? -1:1));
}
};
Story.prototype.tSort_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText){
var elem = this.tSort_refreshTiddler.apply(this,arguments);
if(elem){
var tables = elem.getElementsByTagName("TABLE");
var c = config.tableSorting;
for(var i=0; i<tables.length; i++){
if(hasClass(tables[i],"sortable")){
var x = null, rev, table = tables[i], thead = table.getElementsByTagName('thead')[0], headers = thead.rows[thead.rows.length-1].cells;
for (var j=0; j<headers.length; j++){
var h = headers[j];
if (hasClass(h,"nosort"))
continue;
h.setAttribute("index",j);
h.onclick = function(){c.sortTable(this); return false;};
h.ondblclick = stopEvent;
if(h.getElementsByTagName("span").length == 0)
createTiddlyElement(h,"span",null,"hidden",c.uarrow);
if(!x && hasClass(h,"autosort")) {
x = j;
rev = hasClass(h,"reverse");
}
}
if(x)
c.sortTable(headers[x],rev);
}
}
}
return elem;
};
setStylesheet("table.sortable span.hidden {visibility:hidden;}\n"+
"table.sortable thead {cursor:pointer;}\n"+
"table.sortable .nosort {cursor:default;}\n"+
"table.sortable td.sortedCol {background:#ffc;}","TableSortingPluginStyles");
function stopEvent(e){
var ev = e? e : window.event;
ev.cancelBubble = true;
if (ev.stopPropagation) ev.stopPropagation();
return false;
}
config.macros.nosort={
handler : function(place){
addClass(place,"nosort");
}
};
config.macros.autosort={
handler : function(place,m,p,w,pS){
addClass(place,"autosort"+" "+pS);
}
};
//!END-PLUGIN-CODE
// %/
/***
|''Name:''|~TaggerPlugin|
|''Version:''|1.0.1 (2006-06-01)|
|''Source:''|http://tw.lewcid.org//#TaggerPlugin|
|''Author:''|SaqImtiaz|
|''Description:''|Provides a drop down listing current tiddler tags, and allowing toggling of tags.|
|''Documentation:''|[[TaggerPluginDocumentation]]|
|''Source Code:''|[[TaggerPluginSource]]|
|''~TiddlyWiki:''|Version 2.0.8 or better|
***/
// /%
config.tagger={defaults:{label:"Tags: ",tooltip:"Manage tiddler tags",taglist:"true",excludeTags:"",notags:"tiddler has no tags",aretags:"current tiddler tags:",toggletext:"add tags:"}};config.macros.tagger={};config.macros.tagger.arrow=(document.all?"▼":"▾");config.macros.tagger.handler=function(_1,_2,_3,_4,_5,_6){var _7=config.tagger.defaults;var _8=_5.parseParams("tagman",null,true);var _9=((_8[0].label)&&(_8[0].label[0])!=".")?_8[0].label[0]+this.arrow:_7.label+this.arrow;var _a=((_8[0].tooltip)&&(_8[0].tooltip[0])!=".")?_8[0].tooltip[0]:_7.tooltip;var _b=((_8[0].taglist)&&(_8[0].taglist[0])!=".")?_8[0].taglist[0]:_7.taglist;var _c=((_8[0].exclude)&&(_8[0].exclude[0])!=".")?(_8[0].exclude[0]).readBracketedList():_7.excludeTags.readBracketedList();if((_8[0].source)&&(_8[0].source[0])!="."){var _d=_8[0].source[0];}if(_d&&!store.getTiddler(_d)){return false;}var _e=function(e){if(!e){var e=window.event;}var _11=Popup.create(this);var _12=store.getTags();var _13=new Array();for(var i=0;i<_12.length;i++){_13.push(_12[i][0]);}if(_d){var _15=store.getTiddler(_d);_13=_15.tags.sort();}var _16=_6.tags.sort();var _17=function(_18,_19,_1a){var sp=createTiddlyElement(createTiddlyElement(_11,"li"),"span",null,"tagger");var _1c=createTiddlyButton(sp,_18,_1a+" '"+_19+"'",taggerOnToggle,"button","toggleButton");_1c.setAttribute("tiddler",_6.title);_1c.setAttribute("tag",_19);insertSpacer(sp);if(window.createTagButton_orig_mptw){createTagButton_orig_mptw(sp,_19)}else{createTagButton(sp,_19);}};createTiddlyElement(_11,"li",null,"listTitle",(_6.tags.length==0?_7.notags:_7.aretags));for(var t=0;t<_16.length;t++){_17("[x]",_16[t],"remove tag ");}createTiddlyElement(createTiddlyElement(_11,"li"),"hr");if(_b!="false"){createTiddlyElement(_11,"li",null,"listTitle",_7.toggletext);for(var i=0;i<_13.length;i++){if(!_6.tags.contains(_13[i])&&!_c.contains(_13[i])){_17("[ ]",_13[i],"add tag ");}}createTiddlyElement(createTiddlyElement(_11,"li"),"hr");}var _1f=createTiddlyButton(createTiddlyElement(_11,"li"),("Create new tag"),null,taggerOnToggle);_1f.setAttribute("tiddler",_6.title);if(_d){_1f.setAttribute("source",_d);}Popup.show(_11,false);e.cancelBubble=true;if(e.stopPropagation){e.stopPropagation();}return (false);};createTiddlyButton(_1,_9,_a,_e,"button","taggerDrpBtn");};window.taggerOnToggle=function(e){var tag=this.getAttribute("tag");var _22=this.getAttribute("tiddler");var _23=store.getTiddler(_22);if(!tag){var _24=prompt("Enter new tag:","");if(_24!=""&&_24!=null){var tag=_24;if(this.getAttribute("source")){var _26=store.getTiddler(this.getAttribute("source"));_26.tags.pushUnique(_24);}}else{return false;}}if(!_23||!_23.tags){store.saveTiddler(_22,_22,"",config.options.txtUserName,new Date(),tag);}else{if(_23.tags.find(tag)==null){_23.tags.push(tag);}else{if(!_24){_23.tags.splice(_23.tags.find(tag),1);}}store.saveTiddler(_23.title,_23.title,_23.text,_23.modifier,_23.modified,_23.tags);}story.refreshTiddler(_22,null,true);if(config.options.chkAutoSave){saveChanges();}return false;};setStylesheet(".tagger a.button {font-weight: bold;display:inline; padding:0px;}\n"+".tagger #toggleButton {padding-left:2px; padding-right:2px; margin-right:1px; font-size:110%;}\n"+"#nestedtagger {background:#2E5ADF; border: 1px solid #0331BF;}\n"+".popup .listTitle {color:#000;}\n"+"","TaggerStyles");window.lewcidTiddlerSwapTag=function(_27,_28,_29){for(var i=0;i<_27.tags.length;i++){if(_27.tags[i]==_28){_27.tags[i]=_29;return true;}}return false;};window.lewcidRenameTag=function(e){var tag=this.getAttribute("tag");var _2d=prompt("Rename tag '"+tag+"' to:",tag);if((_2d==tag)||(_2d==null)){return false;}if(store.tiddlerExists(_2d)){if(confirm(config.messages.overwriteWarning.format([_2d.toString()]))){story.closeTiddler(_2d,false,false);}else{return null;}}tagged=store.getTaggedTiddlers(tag);if(tagged.length!=0){for(var j=0;j<tagged.length;j++){lewcidTiddlerSwapTag(tagged[j],tag,_2d);}}if(store.tiddlerExists(tag)){store.saveTiddler(tag,_2d);}if(document.getElementById("tiddler"+tag)){var _2f=document.getElementById(story.idPrefix+tag);var _30=story.positionTiddler(_2f);var _31=document.getElementById(story.container);story.closeTiddler(tag,false,false);story.createTiddler(_31,_30,_2d,null);story.saveTiddler(_2d);}if(config.options.chkAutoSave){saveChanges();}return false;};window.onClickTag=function(e){if(!e){var e=window.event;}var _34=resolveTarget(e);var _35=(!isNested(_34));if((Popup.stack.length>1)&&(_35==true)){Popup.removeFrom(1);}else{if(Popup.stack.length>0&&_35==false){Popup.removeFrom(0);}}var _36=(_35==false)?"popup":"nestedtagger";var _37=createTiddlyElement(document.body,"ol",_36,"popup",null);Popup.stack.push({root:this,popup:_37});var tag=this.getAttribute("tag");var _39=this.getAttribute("tiddler");if(_37&&tag){var _3a=store.getTaggedTiddlers(tag);var _3b=[];var li,r;for(r=0;r<_3a.length;r++){if(_3a[r].title!=_39){_3b.push(_3a[r].title);}}var _3d=config.views.wikified.tag;if(_3b.length>0){var _3e=createTiddlyButton(createTiddlyElement(_37,"li"),_3d.openAllText.format([tag]),_3d.openAllTooltip,onClickTagOpenAll);_3e.setAttribute("tag",tag);createTiddlyElement(createTiddlyElement(_37,"li"),"hr");for(r=0;r<_3b.length;r++){createTiddlyLink(createTiddlyElement(_37,"li"),_3b[r],true);}}else{createTiddlyText(createTiddlyElement(_37,"li",null,"disabled"),_3d.popupNone.format([tag]));}createTiddlyElement(createTiddlyElement(_37,"li"),"hr");var h=createTiddlyLink(createTiddlyElement(_37,"li"),tag,false);createTiddlyText(h,_3d.openTag.format([tag]));createTiddlyElement(createTiddlyElement(_37,"li"),"hr");var _40=createTiddlyButton(createTiddlyElement(_37,"li"),("Rename tag '"+tag+"'"),null,lewcidRenameTag);_40.setAttribute("tag",tag);}Popup.show(_37,false);e.cancelBubble=true;if(e.stopPropagation){e.stopPropagation();}return (false);};if(!window.isNested){window.isNested=function(e){while(e!=null){var _42=document.getElementById("contentWrapper");if(_42==e){return true;}e=e.parentNode;}return false;};}config.shadowTiddlers.TaggerPluginDocumentation="The documentation is available [[here.|http://tw.lewcid.org/#TaggerPluginDocumentation]]";config.shadowTiddlers.TaggerPluginSource="The uncompressed source code is available [[here.|http://tw.lewcid.org/#TaggerPluginSource]]";
// %/
!Stolní počítače
!!![[Intel|Intel x PowerPC]]
[img[http://km.support.apple.com/kb/image.jsp?productid=PL101]]+++^800px^[iMac|iMac] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#imac>>}}}===
[img[http://km.support.apple.com/kb/image.jsp?productid=PL104]]+++^800px^[Mac Pro|Mac Pro] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#macpro>>}}}===
!!![[Intel i PowerPC|Intel x PowerPC]]
[img[http://km.support.apple.com/kb/image.jsp?productid=PL102]]+++^800px^[Mac mini|Mac mini] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#macmini>>}}}===
!!![[PowerPC|Intel x PowerPC]]
[img[http://km.support.apple.com/kb/image.jsp?productid=PL103]]+++^800px^[Power Mac|Power Mac] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#powermac>>}}}===
[img[http://km.support.apple.com/kb/image.jsp?productid=PL100]]+++^800px^[eMac|eMac] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#emac>>}}}===
!!!Starší modely
+++^800px^[Starší modely|Starší modely] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#older>>}}}===
!Notebooky
!!![[Intel|Intel x PowerPC]]
[img[http://km.support.apple.com/kb/image.jsp?productid=PL200]]+++^800px^[Mac Book Air|Mac Book Air] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#macbookair>>}}}===
[img[http://km.support.apple.com/kb/image.jsp?productid=PL107]]+++^800px^[Mac Book Pro|Mac Book Pro] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#macbookpro>>}}}===
[img[http://km.support.apple.com/kb/image.jsp?productid=PL106]]+++^800px^[Mac Book|Mac Book] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#macbook>>}}}===
!!![[PowerPC|Intel x PowerPC]]
[img[http://km.support.apple.com/kb/image.jsp?productid=PL105]]+++^800px^[Power Book|Power Book] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#powerbook>>}}}===
[img[http://km.support.apple.com/kb/image.jsp?productid=PL108]]+++^800px^[iBook|iBook] {{fine block{<<moveablePanel>><<miniBrowser hidecontrols http://support.apple.com/specs/#iBook>>}}}===
/***
|''Name:''|TiddlerNotesPlugin|
|''Description:''|Add notes to tiddlers without modifying the original content|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TiddlerNotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.1|
|''Date:''|26/10/07|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Concept:
*The TiddlerNotesPlugin allows you to add notes to tiddlers, without needing to edit the original tiddler. This means that your original content will remain unaltered, and if you update it in the future, you won’t lose your notes. Notes are stored in separate tiddlers, but can be viewed and edited from within the original tiddler.
*For a tiddler titled "~MySlide", the notes are by default saved in a tiddler titled "~MySlide-Notes" and is given a tag of "Notes". The suffix and tags of the notes tiddlers are customizable. You can have one or multiple notes per tiddlers. So it is possible to have for example, teacher's notes and student's notes in the same file.
*Notes can be configured to start off blank, or pre-filled with the contents of the original tiddler.
!!Usage:
*{{{<<notes>>}}} is the simplest usage form.
* additional optional parameters include:
**{{{heading:}}} the heading to use for the notes box
**{{{tag:}}} the tag to be given to the notes tiddler
**{{{suffix:}}} the suffix to be used when naming the notes tiddler
* a full macro call could look like: {{{<<notes heading:"My Notes" tag:"NoteTiddlers" suffix:"Comments">>}}}
* To avoid adding {{{<<notes>>}}} to each tiddler you want notes for, you could add the macro call to the ViewTemplate
** below the line {{{<div class='viewer' macro='view text wikified'></div>}}} add the following line: <br> {{{<div class='viewer' macro='notes'></div>}}}
** Used in combination with the ~HideWhenPlugin or ~PublisherPlugin, you could have notes be shown only for tiddlers with specific tags. The ~PublisherPlugin would allow you for instance to only have the ~TeachersNotes visible to the teacher, and the ~StudentsNotes for the same tiddler visible to the Student.
!!Configuration
*<<option chkPrefillNotes>> Enable to pre-fill notes with the original tiddler's contents
!!Demo:
* [[MySlide]]
***/
// /%
//!BEGIN-PLUGIN-CODE
if (!config.options.chkPrefillNotes)
config.options.chkPrefillNotes = false;
function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
{
var e = document.createElement(theElement);
if(theClass != null)
e.className = theClass;
if(theID != null)
e.setAttribute("id",theID);
if(theText != null)
e.appendChild(document.createTextNode(theText));
if(attribs){
for(var n in attribs){
e.setAttribute(n,attribs[n]);
}
}
if(theParent != null)
theParent.appendChild(e);
return e;
}
function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey,attribs)
{
var theButton = document.createElement("a");
if(theAction) {
theButton.onclick = theAction;
theButton.setAttribute("href","javascript:;");
}
if(theTooltip)
theButton.setAttribute("title",theTooltip);
if(theText)
theButton.appendChild(document.createTextNode(theText));
if(theClass)
theButton.className = theClass;
else
theButton.className = "button";
if(theId)
theButton.id = theId;
if(attribs){
for(var n in attribs){
e.setAttribute(n,attribs[n]);
}
}
if(theParent)
theParent.appendChild(theButton);
if(theAccessKey)
theButton.setAttribute("accessKey",theAccessKey);
return theButton;
}
config.macros.notes={
cancelWarning: "Are you sure you want to abandon changes to your notes for '%0'?",
editLabel: "edit notes",
editTitle: "double click to edit",
saveLabel: "save notes",
saveTitle: "double click to save",
cancelLabel: "cancel",
heading: "Notes",
suffix: "Notes",
tag: "Notes",
saveNotes: function(ev){
e = ev? ev : window.event;
var theTarget = resolveTarget(e);
if (theTarget.nodeName.toLowerCase() == "textarea")
return false;
var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
story.setDirty(title,false);
var box = document.getElementById("notesContainer"+title);
var textarea = document.getElementById("notesTextArea"+title);
if(textarea.getAttribute("oldText")!=textarea.value && !hasClass(theTarget,"cancelNotesButton")){
var suffix = box.getAttribute("suffix");
var t = store.getTiddler(title+"-"+suffix);
store.saveTiddler(title+"-"+suffix,title+"-"+suffix,textarea.value,config.options.txtUserName,new Date(),t?t.tags:box.getAttribute("tag"),t?t.fields:{});
}
story.refreshTiddler(title,1,true);
autoSaveChanges(true);
return false;
},
editNotes: function(box,tiddler){
removeChildren(box);
story.setDirty(tiddler,true);
box.title = this.saveTitle;
box.ondblclick = this.saveNotes;
createTiddlyButton(box,this.cancelLabel,this.cancelLabel,this.saveNotes,"cancelNotesButton");
createTiddlyButton(box,this.saveLabel,this.saveLabel,this.saveNotes,"saveNotesButton");
wikify("!!"+box.getAttribute("heading")+"\n",box);
addClass(box,"editor");
var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
var wrapper2 = createTiddlyElement(wrapper1,"div");
var e = createTiddlyElement(wrapper2,"textarea","notesTextArea"+tiddler);
var v = store.getValue(tiddler+"-"+box.getAttribute("suffix"),"text");
if(!v)
v = config.options.chkPrefillNotes? store.getValue(tiddler,"text"):'';
e.value = v;
e.setAttribute("oldText",v);
var rows = 10;
var lines = v.match(/\n/mg);
var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
if(lines != null && lines.length > rows)
rows = lines.length + 5;
rows = Math.min(rows,maxLines);
e.setAttribute("rows",rows);
box.appendChild(wrapper1);
},
editNotesButtonOnclick: function(e){
var title = story.findContainingTiddler(this).getAttribute("tiddler");
var box = document.getElementById("notesContainer"+title);
config.macros.notes.editNotes(box,title);
return false;
},
ondblclick : function(ev){
e = ev? ev : window.event;
var theTarget = resolveTarget(e);
var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
var box = document.getElementById("notesContainer"+title);
config.macros.notes.editNotes(box,title);
e.cancelBubble = true;
if(e.stopPropagation) e.stopPropagation();
return false;
},
handler : function(place,macroName,params,wikifier,paramString,tiddler){
params = paramString.parseParams("anon",null,true,false,false);
var heading = getParam(params,"heading",this.heading);
var tag = getParam(params,"tag",this.tag);
var suffix = getParam(params,"suffix",this.suffix);
var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tag:tag,suffix:suffix});
createTiddlyButton(box,this.editLabel,this.editLabel,this.editNotesButtonOnclick,"editNotesButton");
wikify("!!"+heading+"\n",box);
box.title=this.editTitle;
box.ondblclick = this.ondblclick;
wikify("<<tiddler [["+tiddler.title+"-"+suffix+"]]>>",box);
}
};
Story.prototype.old_notes_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,unused){
if(story.isDirty(title)) {
if(!confirm(config.macros.notes.cancelWarning.format([title])))
return false;
}
return this.old_notes_closeTiddler.apply(this,arguments);
}
setStylesheet(".TiddlerNotes {\n"+ " background:#eee;\n"+ " border:1px solid #ccc;\n"+ " padding:10px;\n"+ " margin:15px;\n"+ "}\n"+ "\n"+ ".cancelNotesButton,.editNotesButton, .saveNotesButton {\n"+ " float:right;\n"+ " border:1px solid #ccc;\n"+ " padding:2px 5px;\n"+ "}\n"+ "\n"+ ".saveNotesButton{\n"+ " margin-right:0.5em;\n"+ "}\n"+ "\n"+ ".TiddlerNotes.editor textarea{\n"+ " border:1px solid #ccc;\n"+ "}","NotesPluginStyles");
//!END-PLUGIN-CODE
// %/
/***
|''Name:''|TiddlersBarPlugin|
|''Description:''|A bar to switch between tiddlers through tabs (like browser tabs bar).|
|''Version:''|1.2.5|
|''Date:''|Jan 18,2008|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demos
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], open several tiddlers to use the tabs bar.
!Installation
#import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
#save and reload
#''if you're using a custom [[PageTemplate]]'', add {{{<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>}}} before {{{<div id='tiddlerDisplay'></div>}}}
#optionally, adjust StyleSheetTiddlersBar
!Tips
*Doubleclick on the tiddlers bar (where there is no tab) create a new tiddler.
*Tabs include a button to close {{{x}}} or save {{{!}}} their tiddler.
*By default, click on the current tab close all others tiddlers.
!Configuration options
<<option chkDisableTabsBar>> Disable the tabs bar (to print, by example).
<<option chkHideTabsBarWhenSingleTab >> Automatically hide the tabs bar when only one tiddler is displayed.
<<option txtSelectedTiddlerTabButton>> ''selected'' tab command button.
<<option txtPreviousTabKey>> previous tab access key.
<<option txtNextTabKey>> next tab access key.
!Code
***/
//{{{
config.options.chkDisableTabsBar = config.options.chkDisableTabsBar ? config.options.chkDisableTabsBar : false;
config.options.chkHideTabsBarWhenSingleTab = config.options.chkHideTabsBarWhenSingleTab ? config.options.chkHideTabsBarWhenSingleTab : false;
config.options.txtSelectedTiddlerTabButton = config.options.txtSelectedTiddlerTabButton ? config.options.txtSelectedTiddlerTabButton : "closeOthers";
config.options.txtPreviousTabKey = config.options.txtPreviousTabKey ? config.options.txtPreviousTabKey : "";
config.options.txtNextTabKey = config.options.txtNextTabKey ? config.options.txtNextTabKey : "";
config.macros.tiddlersBar = {
tooltip : "see ",
tooltipClose : "click here to close this tab",
tooltipSave : "click here to save this tab",
promptRename : "Enter tiddler new name",
currentTiddler : "",
previousState : false,
previousKey : config.options.txtPreviousTabKey,
nextKey : config.options.txtNextTabKey,
tabsAnimationSource : null, //use document.getElementById("tiddlerDisplay") if you need animation on tab switching.
handler: function(place,macroName,params) {
var previous = null;
if (config.macros.tiddlersBar.isShown())
story.forEachTiddler(function(title,e){
if (title==config.macros.tiddlersBar.currentTiddler){
var d = createTiddlyElement(null,"span",null,"tab tabSelected");
config.macros.tiddlersBar.createActiveTabButton(d,title);
if (previous && config.macros.tiddlersBar.previousKey) previous.setAttribute("accessKey",config.macros.tiddlersBar.nextKey);
previous = "active";
}
else {
var d = createTiddlyElement(place,"span",null,"tab tabUnselected");
var btn = createTiddlyButton(d,title,config.macros.tiddlersBar.tooltip + title,config.macros.tiddlersBar.onSelectTab);
btn.setAttribute("tiddler", title);
if (previous=="active" && config.macros.tiddlersBar.nextKey) btn.setAttribute("accessKey",config.macros.tiddlersBar.previousKey);
previous=btn;
}
var isDirty =story.isDirty(title);
var c = createTiddlyButton(d,isDirty ?"!":"x",isDirty?config.macros.tiddlersBar.tooltipSave:config.macros.tiddlersBar.tooltipClose, isDirty ? config.macros.tiddlersBar.onTabSave : config.macros.tiddlersBar.onTabClose,"tabButton");
c.setAttribute("tiddler", title);
if (place.childNodes) {
place.insertBefore(document.createTextNode(" "),place.firstChild); // to allow break line here when many tiddlers are open
place.insertBefore(d,place.firstChild);
}
else place.appendChild(d);
})
},
refresh: function(place,params){
removeChildren(place);
config.macros.tiddlersBar.handler(place,"tiddlersBar",params);
if (config.macros.tiddlersBar.previousState!=config.macros.tiddlersBar.isShown()) {
story.refreshAllTiddlers();
if (config.macros.tiddlersBar.previousState) story.forEachTiddler(function(t,e){e.style.display="";});
config.macros.tiddlersBar.previousState = !config.macros.tiddlersBar.previousState;
}
},
isShown : function(){
if (config.options.chkDisableTabsBar) return false;
if (!config.options.chkHideTabsBarWhenSingleTab) return true;
var cpt=0;
story.forEachTiddler(function(){cpt++});
return (cpt>1);
},
selectNextTab : function(){ //used when the current tab is closed (to select another tab)
var previous="";
story.forEachTiddler(function(title){
if (!config.macros.tiddlersBar.currentTiddler) {
story.displayTiddler(null,title);
return;
}
if (title==config.macros.tiddlersBar.currentTiddler) {
if (previous) {
story.displayTiddler(null,previous);
return;
}
else config.macros.tiddlersBar.currentTiddler=""; // so next tab will be selected
}
else previous=title;
});
},
onSelectTab : function(e){
var t = this.getAttribute("tiddler");
if (t) story.displayTiddler(null,t);
return false;
},
onTabClose : function(e){
var t = this.getAttribute("tiddler");
if (t) {
if(story.hasChanges(t) && !readOnly) {
if(!confirm(config.commands.cancelTiddler.warning.format([t])))
return false;
}
story.closeTiddler(t);
}
return false;
},
onTabSave : function(e) {
var t = this.getAttribute("tiddler");
if (!e) e=window.event;
if (t) config.commands.saveTiddler.handler(e,null,t);
return false;
},
onSelectedTabButtonClick : function(event,src,title) {
var t = this.getAttribute("tiddler");
if (!event) event=window.event;
if (t && config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton])
config.commands[config.options.txtSelectedTiddlerTabButton].handler(event, src, t);
return false;
},
onTiddlersBarAction: function(event) {
var source = event.target ? event.target.id : event.srcElement.id; // FF uses target and IE uses srcElement;
if (source=="tiddlersBar") story.displayTiddler(null,'New Tiddler',DEFAULT_EDIT_TEMPLATE,false,null,null);
},
createActiveTabButton : function(place,title) {
if (config.options.txtSelectedTiddlerTabButton && config.commands[config.options.txtSelectedTiddlerTabButton]) {
var btn = createTiddlyButton(place, title, config.commands[config.options.txtSelectedTiddlerTabButton].tooltip ,config.macros.tiddlersBar.onSelectedTabButtonClick);
btn.setAttribute("tiddler", title);
}
else
createTiddlyText(place,title);
}
}
story.coreCloseTiddler = story.coreCloseTiddler? story.coreCloseTiddler : story.closeTiddler;
story.coreDisplayTiddler = story.coreDisplayTiddler ? story.coreDisplayTiddler : story.displayTiddler;
story.closeTiddler = function(title,animate,unused) {
if (title==config.macros.tiddlersBar.currentTiddler)
config.macros.tiddlersBar.selectNextTab();
story.coreCloseTiddler(title,false,unused); //disable animation to get it closed before calling tiddlersBar.refresh
var e=document.getElementById("tiddlersBar");
if (e) config.macros.tiddlersBar.refresh(e,null);
}
story.displayTiddler = function(srcElement,tiddler,template,animate,unused,customFields,toggle){
story.coreDisplayTiddler(config.macros.tiddlersBar.tabsAnimationSource,tiddler,template,animate,unused,customFields,toggle);
var title = (tiddler instanceof Tiddler)? tiddler.title : tiddler;
if (config.macros.tiddlersBar.isShown()) {
story.forEachTiddler(function(t,e){
if (t!=title) e.style.display="none";
else e.style.display="";
})
config.macros.tiddlersBar.currentTiddler=title;
}
var e=document.getElementById("tiddlersBar");
if (e) config.macros.tiddlersBar.refresh(e,null);
}
var coreRefreshPageTemplate = coreRefreshPageTemplate ? coreRefreshPageTemplate : refreshPageTemplate;
refreshPageTemplate = function(title) {
coreRefreshPageTemplate(title);
if (config.macros.tiddlersBar) config.macros.tiddlersBar.refresh(document.getElementById("tiddlersBar"));
}
ensureVisible=function (e) {return 0} //disable bottom scrolling (not useful now)
config.shadowTiddlers.StyleSheetTiddlersBar = "/*{{{*/\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .button {border:0}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar .tab {white-space:nowrap}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += "#tiddlersBar {padding : 1em 0.5em 2px 0.5em}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tabUnselected .tabButton, .tabSelected .tabButton {padding : 0 2px 0 2px; margin: 0 0 0 4px;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar += ".tiddler, .tabContents {border:1px [[ColorPalette::TertiaryPale]] solid;}\n";
config.shadowTiddlers.StyleSheetTiddlersBar +="/*}}}*/";
store.addNotification("StyleSheetTiddlersBar", refreshStyles);
config.refreshers.none = function(){return true;}
config.shadowTiddlers.PageTemplate=config.shadowTiddlers.PageTemplate.replace(/<div id='tiddlerDisplay'><\/div>/m,"<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>\n<div id='tiddlerDisplay'></div>");
//}}}
http://www.majstudio.com/divadlo/huceni.mp3
Bridge – Martin Jirsak MAJ; scenic music
----
http://www.majstudio.com/divadlo/Smycka.mp3
Loop – Martin Jirsak MAJ; scenic music
----
http://www.majstudio.com/data/Depeche_32.mp3
Depeche – Martin Jirsak MAJ
----
http://www.majstudio.com/data/pavlik.mp3
Paul – Martin Jirsak MAJ; rock
----
http://www.majstudio.com/data/Tono.mp3
Tono – Martin Jirsak MAJ
----
/***
|Name|TiddlyPodPlugin|
|Source|http://www.TiddlyTools.com/#TiddlyPodPlugin|
|Version|1.4.3|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|TiddlyPodList|
|Overrides||
|Description|autoplay music randomly selected from playlist using embedded player|
!!!!!Usage
<<<
{{{<<tiddlyPod autoplay loop track:# @TiddlerName>>}}}
where optional parameters are:
* ''autoplay'' / ''noautoplay'' - this keyword causes a selection to being playing as soon as it has been loaded into the TiddlyPod player, without needed to press the player's PLAY button. You can also manually change this setting via the TiddlyPod playlist popup. The manual setting is tracked in a browser cookie and, if a macro parameter option is not specified, the most recent manually selected setting is used.
* ''loop'' / ''noloop'' - this keyword causes the current tune to be repeatedly played until you press the stop button. You can also manually change this setting via the TiddlyPod playlist popup. The manual setting is tracked in a browser cookie and, if a macro parameter option is not specified, the most recent manually selected setting is used.
* ''verbose'' - this keyword causes a message to be displayed whenever a tune is selected.
* ''track:#'' - specifies the index into the playlist for the initial tune to load into the player. Combined with 'autoplay' this allows you to define a fixed 'startup sound' for your document. If no track is specified, the last tune played is re-loaded (tracked in a browser cookie). If no cookie exists (i.e., the first time you play after installing, or after clearing cookies, etc.), then the first tune in the playlist is used.
* ''@~TiddlerName'' - specifies a tiddler containing the list of tunes to play. The default "playlist" is stored in [[TiddlyPodList]]. Entries in the list are separated by "----", and each entry consist of two lines: the first line is the location (or URL) of the media file to be played. The second line is a title to be displayed when that item is playing.
* ''listlength:xxxx'' - specifies the height of the playlist popup (using CSS measurement units, e.g., "px", "em", "cm", "in", etc.). If the number of items in the list exceed this length, then a scrollbar is automatically added to the popup list. Default is to show all playlist entries without scrolling and is equivalent to specifying "listlength:auto".
<<<
!!!!!Examples
<<<
{{{<<tiddlyPod noautoplay loop track:1 @TiddlyPodList>>}}}
<<tiddlyPod noautoplay loop track:1 @TiddlyPodList>>
<<<
!!!!!Revisions
<<<
2008.03.21 [1.4.3] removed {{{pluginspage="http://www.apple.com/quicktime/download/"}}} param from HTML {{{<embed>}}}, so that FireFox (and other browsers) don't //prefer// QuickTime over other installed media players. It is up to the browser to determine which player to use.
2007.11.09 [1.4.2] in handler(), corrected default initialization of chkTiddlyPodAutoPlay and chkTiddlyPodLoopPlay.
2007.06.12 [1.4.1] in play(), don't call removeChildren(), since browser will clean up objects when assignment to innerHTML is made
2007.02.23 [1.4.0] added support for using 'attachment tiddlers' (see AttachFilePlugin) for self-contained playback. This seems to work well with QuickTime. Other embedded players may vary in support for the data:// URI. Note: IE6/7 does NOT support data:// URI. Attachments should always have local and/or remote fallbacks defined.
2007.02.23 [1.3.1] added support for scrollbar to playlist popup. Use listlength:xxx to set the length of the playlist, where 'xxx' is any valid CSS measurement. Use "auto" to show all playlist items without scrolling. Also, added popup items for controlling autoplay/loopplay preferences.
2007.02.21 [1.3.0] added playlist popup and rewrote getPod() and play() to use innerHTML instead of wikify(). Eliminates all dependency on InlineJavascriptPlugin when rendering output.
2007.02.20 [1.2.1] added optional 'track:#' parameter to specify initial track, instead of starting with a random track
2007.02.20 [1.2.0] added optional 'loop' parameter to trigger looping playback
2007.02.20 [1.1.0] removed link for "edit playlist" to reduce clutter and provide a 'playback only' interface. When changing the play list is appropriate, a link to [[TiddlyPodList]] (or any alternative playlist tiddler) can be directly added to surrounding tiddler content as needed.
2007.02.19 [1.0.0] initial release (converted from inline script)
<<<
!!!!!Code
***/
//{{{
version.extensions.tiddlyPod= {major: 1, minor: 4, revision: 3, date: new Date(2008,3,21)};
config.macros.tiddlyPod= {
verbose: false, // set to true to display messages
playlist: "TiddlyPodList", // tiddler containing list of tunes
listlength: "auto", // maximum length (using CSS) of playlist to show before adding a scrollbar
width: config.browser.isIE?90:115, // width of embedded player (IE w/WinMedia vs FireFox w/QuickTime)
height: config.browser.isIE?44:15, // height of embedded player (IE w/WinMedia vs FireFox w/QuickTime)
getPlayer: function(src,w,h,auto,loop) {
var out='';
out+='<EMBED WIDTH="'+w+'" HEIGHT="'+h+'" ';
out+=' style="height:'+h+'px;width:'+w+'px;margin:0;padding:0;" ';
out+=' src="'+src+'" ';
out+=' autostart="'+(auto?'true':'false')+'" autoplay="'+(auto?'true':'false')+'" ';
out+=' loop="'+(loop?'true':'false')+'" ';
out+=' controller="show" volume="100" EnableJavaScript="true" ';
out+=' showtracker="1" showpositioncontrols="0" showaudiocontrols="0" ';
out+=' showdisplay="0" showstatusbar="0" showgotobar="0"> ';
out+='</EMBED>';
return out;
},
getPod: function(playlist,which) {
var txt=store.getTiddlerText(playlist); if (!txt) return;
var songs=txt.split("\n----\n");
var first=0;
var last=songs.length-1;
if (which===undefined) which=config.options.txtTiddlyPodNowPlaying;
if (which<first) which=first; if (which>last) which=last;
var next=(which-1)+2; if (next>last) next=last;
var prev=which-1; if (prev<first) prev=first;
var src=songs[which].split("\n")[0];
var descr=songs[which].split("\n")[1];
// if src is a tiddlername, check for attachment
if (config.macros.attach!=undefined) // if AttachFilePlugin is installed
if ((tid=store.getTiddler(src))!=null && tid.isTagged("attachment")) // if src is attachment tiddler title
src=config.macros.attach.getAttachment(src); // replace TiddlerTitle with attachment-expanded src URL
var out='';
var tip=config.messages.externalLinkTooltip.format([src]); // use core defined tooltip
out+='<div><a href="'+src+'" target="_blank" class="button" title="'+tip+'" style="white-space:normal">'+descr+'</a></div>';
out+=this.getPlayer(src,this.width,this.height,config.options.chkTiddlyPodAutoPlay,config.options.chkTiddlyPodLoopPlay);
out+='<div class="small">';
out+='<a href="javascript:;" class="button" title="[first] track '+(first+1)+' - '+songs[first].split("\n")[1]+'" ';
out+=' onclick="config.macros.tiddlyPod.play(this.parentNode.parentNode,'+first+'); return false;"><<</a>';
out+=' ';
out+='<a href="javascript:;" class="button" title="[previous] track '+(prev+1)+' - '+songs[prev].split("\n")[1]+'" ';
out+=' onclick="config.macros.tiddlyPod.play(this.parentNode.parentNode,'+prev+'); return false;"> < </a>';
out+=' ';
out+='<a href="javascript:;" class="button" title="[playlist]" ';
out+=' onclick="config.macros.tiddlyPod.showpopup(this,event);">...</a>';
out+=' ';
out+='<a href="javascript:;" class="button" title="[next] track '+(next+1)+' - '+songs[next].split("\n")[1]+'" ';
out+=' onclick="config.macros.tiddlyPod.play(this.parentNode.parentNode,'+next+'); return false;"> > </a>';
out+=' ';
out+='<a href="javascript:;" class="button" title="[last] track '+(last+1)+' - '+songs[last].split("\n")[1]+'" ';
out+=' onclick="config.macros.tiddlyPod.play(this.parentNode.parentNode,'+last+'); return false;">>></a>';
out+='</div>';
if (this.verbose) displayMessage('now playing... track '+(which+1)+' - "'+descr+'"');
return out;
},
play: function(target,which) {
if (which==undefined) which=config.options.txtTiddlyPodNowPlaying; // if not specified, use most recently played item
if (which==undefined) which=0; // default to first item in playlist if no previous item
target.innerHTML=this.getPod(this.playlist,which);
config.options.txtTiddlyPodNowPlaying=which;
saveOptionCookie("txtTiddlyPodNowPlaying");
return;
},
showpopup: function(place,event) {
var popup=Popup.create(place); if (!popup) return;
var txt=store.getTiddlerText(this.playlist); if (!txt) return;
var songs=txt.split("\n----\n");
config.macros.tiddlyPod.target=place.parentNode.parentNode;
createTiddlyButton(createTiddlyElement(popup,'li'),
"play a randomly selected track", "shuffle play",
function(){
var t=config.options.chkTiddlyPodAutoPlay;
config.options.chkTiddlyPodAutoPlay=true; // force autoplay
config.macros.tiddlyPod.play(config.macros.tiddlyPod.target,Math.floor(Math.random()*songs.length));
config.options.chkTiddlyPodAutoPlay=t;
});
createTiddlyElement(popup,"hr");
createTiddlyButton(createTiddlyElement(popup,'li'),
(config.options.chkTiddlyPodAutoPlay?"[x]":"[_]")+" auto play",
"automatically play tune when selected (if off, press PLAY button to start)",
function(){
config.options.chkTiddlyPodAutoPlay=!config.options.chkTiddlyPodAutoPlay;
saveOptionCookie("chkTiddlyPodAutoPlay");
config.macros.tiddlyPod.play(config.macros.tiddlyPod.target,config.options.txtTiddlyPodNowPlaying);
});
createTiddlyButton(createTiddlyElement(popup,'li'),
(config.options.chkTiddlyPodLoopPlay?"[x]":"[_]")+" repeat play",
"when playback is finished, repeat the current selection again",
function(){
config.options.chkTiddlyPodLoopPlay=!config.options.chkTiddlyPodLoopPlay;
saveOptionCookie("chkTiddlyPodLoopPlay");
config.macros.tiddlyPod.play(config.macros.tiddlyPod.target,config.options.txtTiddlyPodNowPlaying);
});
createTiddlyElement(popup,"hr");
var playlist=createTiddlyElement(popup,"div",null,"fine"); // uses 'fine' CSS class to set font size
playlist.style.padding="2px"; // room for dotted 'focus' indicator (prevent horizontal scrollbar from appearing)
playlist.style.height=config.macros.tiddlyPod.listlength;
playlist.style.overflow="auto";
for (var s=0; s<songs.length; s++) {
var src=songs[s].split("\n")[0];
var descr=(s+1)+" - "+songs[s].split("\n")[1];
var a=createTiddlyButton(createTiddlyElement(playlist,'li'), descr, src,
function(){
var t=config.options.chkTiddlyPodAutoPlay;
config.options.chkTiddlyPodAutoPlay=true; // force autoplay
config.macros.tiddlyPod.play(config.macros.tiddlyPod.target,this.getAttribute("which"));
config.options.chkTiddlyPodAutoPlay=t;
});
a.setAttribute("which",s); // song index
if (s==config.options.txtTiddlyPodNowPlaying) a.style.fontWeight="bold";
}
createTiddlyElement(popup,"hr");
createTiddlyButton(createTiddlyElement(popup,'li'), 'edit playlist...', '',
function(){story.displayTiddler(null,config.macros.tiddlyPod.playlist,2)});
Popup.show(popup,false);
if (!event) var event=window.event;
if (event) event.cancelBubble = true;
if (event && event.stopPropagation) event.stopPropagation();
},
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
if (config.options.chkTiddlyPodAutoPlay==undefined)
config.options.chkTiddlyPodAutoPlay=true; // default enable auto play
if (config.options.chkTiddlyPodLoopPlay==undefined)
config.options.chkTiddlyPodLoopPlay=false; // default disable loop play
if (config.options.chkTiddlyPodNowPlaying==undefined)
config.options.chkTiddlyPodNowPlaying=0; // default to first item in playlist
while (p=params.shift()) {
if (p=="autoplay")
config.options.chkTiddlyPodAutoPlay=true; // enable auto play
if (p=="noautoplay")
config.options.chkTiddlyPodAutoPlay=false; // disable auto play
else if (p=="loop")
config.options.chkTiddlyPodLoopPlay=true; // enable loop play
else if (p=="noloop")
config.options.chkTiddlyPodLoopPlay=false; // disable loop play
else if (p=="verbose")
this.verbose=true; // enable message display
else if (p.substr(0,1)=="@")
this.playlist=p.substr(1); // alternative playlist tiddler
else if (p.substr(0,6)=="track:")
config.options.txtTiddlyPodNowPlaying=p.substr(6)-1; // initial playlist index (0-based, e.g. track #1=index 0)
else if (p.substr(0,6)=="width:")
this.width=p.substr(6); // width of embedded player controls
else if (p.substr(0,7)=="height:")
this.height=p.substr(7); // height of embedded player controls
else if (p.substr(0,11)=="listlength:")
this.listlength=p.substr(11); // height of playlist in popup
}
this.play(createTiddlyElement(place,"span"),config.options.txtTiddlyPodNowPlaying);
}
}
//}}}
//(source:[[Wikipedia|http://en.wikipedia.org/wiki/Tiddlywiki]])//
TiddlyWiki is a wiki-modeled client-side single page application written by Jeremy Ruston that is designed to be used as a personal notebook. It is a single self-contained HTML file that includes CSS and JavaScript code. When the user downloads it to their PC, TiddlyWiki can save the entered information by overwriting itself on the user's disk, at the user's request. Following TiddlyWiki conventions, users can make a new entry, called a Tiddler, in their local copy of the TiddlyWiki file and save it for future reference. Existing Tiddlers can also be modified or deleted in the same way.
More on http://tiddlywiki.com
/***
|''Name:''|WikiBar|
|''Version:''|2.0.0 beta3|
|''Source:''|[[AiddlyWiki|http://aiddlywiki.sourceforge.net]]|
|''Author:''|[[Arphen Lin|mailto:arphenlin@gmail.com]]|
|''Type:''|toolbar macro command extension|
|''Required:''|TiddlyWiki 2.0.0 beta6|
!Description
WikiBar is a toolbar that gives access to most of TiddlyWiki's formatting features with a few clicks. It's a handy tool for people who are not familiar with TiddlyWiki syntax.
Besides, with WikiBar-addons, users can extend the power of WikiBar.
!Support browser
*Firefox 1.5
!Revision history
*v2.0.0 beta3 (2005/12/30)
** remove macros (replaced by TWMacro addon)
** add wikibar command in toolbar automatically
** rename DOIT to HANDLER
** rename TIP to TOOLTIP
*v2.0.0 beta2 (2005/12/21)
** re-design Wikibar addon framework
*v2.0.0 beta1 (2005/12/14)
** Note:
*** WikiBarPlugin is renamed to WikiBar
** New Features:
*** support TiddlyWiki 2.0.0 template mechanism
*** new wikibar data structure
*** new wikibar-addon framework for developers
**** support dynamic popup menu generator
*** support most new macros added in TiddlyWiki 2.0.0
*** multi-level popup menu
*** fix wikibar tab stop
*** remove paletteSelector
** Known Bugs:
*** popup-menu and color-picker can't be closed correctly
*** some macros can't be displayed correctly in previewer
*** text in previewer will be displayed italic
*v1.2.0 (2005/11/21)
**New Features:
***User defined color palettes supported
####Get color palettes from [[ColorZilla Palettes|http://www.iosart.com/firefox/colorzilla/palettes.html]].
####Save the palette file(*.gpl) as a new tiddler and tag it with 'ColorPalettes', then you can use it in WikiBar.
***WikiBar style sheet supported
***Click on document to close current colorPicker, paletteSelector or aboutWikibar
*v1.1.1 (2005/11/03)
**Bugs fixed:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.1.0 (2005/11/01)
**Bugs fixed:
***WikiBar overruns (reported by by GeoffS <gslocock@yahoo.co.uk>)
**New features:
***Insert a color code at the cursor. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Enable gradient macro. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Insert tiddler comment tags {{{/% ... %/}}}. (new feature supported by TiddlyWiki 1.2.37)
***Insert DateFormatString for {{{<<today>>}}} macro. (new feature supported by TiddlyWiki 1.2.37)
**Enhanced:
***Allow optional parameters in syntax.
**Bugs:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.0.0 (2005/10/30)
**Initial release
!Code
***/
//{{{
config.macros.wikibar = {major: 2, minor: 0, revision: 0, beta: 3, date: new Date(2005,12,30)};
config.macros.wikibar.handler = function(place,macroName,params,wikifier,paramString,tiddler){
if(!(tiddler instanceof Tiddler)) {return;}
story.setDirty(tiddler.title,true);
place.id = 'wikibar'+tiddler.title;
place.className = 'toolbar wikibar';
};
function wikibar_install(){
config.commands.wikibar = {
text: 'wikibar',
tooltip: 'wikibar on/off',
handler: function(e,src,title) {
if(!e){ e = window.event; }
var theButton = resolveTarget(e);
theButton.id = 'wikibarButton'+title;
wikibarPopup.remove();
wikibar_installAddons(theButton, title);
wikibar_createWikibar(title);
return(false);
}
};
config.shadowTiddlers['EditTemplate'] = wikibar_addWikibarCommand(config.shadowTiddlers['EditTemplate']);
var tiddler = store.getTiddler('EditTemplate');
if(tiddler){
tiddler.text = wikibar_addWikibarCommand(tiddler.text);
}
}
function wikibar_installAddons(theButton, title){
var tiddlers = store.getTaggedTiddlers('wikibarAddons');
if(!tiddlers) { return; }
theButton.addons=[];
for(var i=0; i<tiddlers.length; i++){
try{
eval(tiddlers[i].text);
try{
wikibar_addonInstall(title);
wikibar_addonInstall = null;
theButton.addons.push({ok:true, name:tiddlers[i].title});
}catch(ex){
theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
}
}catch(ex){
theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
}
}
}
function wikibar_addWikibarCommand(tiddlerText){
var div = document.createElement('div');
div.style.display = 'none';
div.innerHTML = tiddlerText;
for(var i=0; i<div.childNodes.length; i++){
var o=div.childNodes[i];
if(o.tagName==='DIV'){
if(o.className=='toolbar'){
var macroText = o.getAttribute('macro').trim();
if(macroText.search('wikibar')<=0){
macroText += ' wikibar';
o.setAttribute('macro', macroText);
}
break;
}
}
}
return div.innerHTML.replace(/\"/g, "\'");
}
function wikibar_processSyntaxParams(theSyntax, params){
try{
var pcr = 'AplWikibarPcr';
var rx=null;
var allParams=null;
if(params){
if(typeof(params)=='object'){
for(var i=0; i<params.length; i++){
if(params[i]){
params[i] = params[i].replace(new RegExp('%','g'), pcr).trim();
rx = '(\\[%'+(i+1)+'\\])' + '|' + '(%'+(i+1)+')';
theSyntax = theSyntax.replace(new RegExp(rx,'g'), params[i] );
}
}
allParams = params.join(' ').trim();
}else{
allParams = params.replace(new RegExp('%','g'), pcr).trim();
rx = /(\[%1{1}\])|(%1{1})/g;
theSyntax = theSyntax.replace(rx, allParams);
}
}
if(allParams){
theSyntax = theSyntax.replace(new RegExp('%N{1}','g'), allParams);
}
rx=/\[%(([1-9]{1,}[0-9]{0,})|(N{1}))\]/g;
theSyntax = theSyntax.replace(rx, '');
rx=/%(([1-9]{1,}[0-9]{0,})|(N{1}))/g;
if( theSyntax.match(rx) ){
throw 'Not enough parameters! ' + theSyntax;
}
theSyntax=theSyntax.replace(new RegExp(pcr,'g'), '%');
return theSyntax;
} catch(ex){
return null;
}
}
function wikibar_resolveEditItem(tiddlerWrapper, itemName){
if(tiddlerWrapper.hasChildNodes()){
var c=tiddlerWrapper.childNodes;
for(var i=0; i<c.length; i++){
var txt=wikibar_resolveEditItem(c[i], itemName);
if(!txt){
continue;
}else{
return txt;
}
}
}
return ((tiddlerWrapper.getAttribute && tiddlerWrapper.getAttribute('edit')==itemName)? tiddlerWrapper : null);
}
function wikibar_resolveEditItemValue(tiddlerWrapper, itemName){
var o = wikibar_resolveEditItem(tiddlerWrapper, itemName);
return (o? o.value.replace(/\r/mg,'') : null);
}
function wikibar_resolveTiddlerEditorWrapper(obj){
if(obj.id=='tiddlerDisplay'){return null;}
if((obj.getAttribute && obj.getAttribute('macro')=='edit text')){return obj;}
return wikibar_resolveTiddlerEditorWrapper(obj.parentNode);
}
function wikibar_resolveTiddlerEditor(obj){
if(obj.hasChildNodes()){
var c = obj.childNodes;
for(var i=0; i<c.length; i++){
var o=wikibar_resolveTiddlerEditor(c[i]);
if(o){ return o;}
}
}
return ((obj.getAttribute && obj.getAttribute('edit')=='text')? obj : null);
}
function wikibar_resolveTargetButton(obj){
if(obj.id && obj.id.substring(0,7)=='wikibar'){ return null; }
if(obj.tiddlerTitle){
return obj;
}else{
return wikibar_resolveTargetButton(obj.parentNode);
}
}
function wikibar_isValidMenuItem(tool){
if(!tool){ return false; }
if(tool.TYPE=='MENU' || tool.TYPE=='MAIN_MENU'){
for(var key in tool){
if(key.substring(0,8)=='DYNAITEM'){ return true; }
if(wikibar_isValidMenuItem(tool[key])){ return true; }
}
return false;
}else{
return (tool.HANDLER? true : false);
}
}
function wikibar_editFormat(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByWord(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){return;}
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
if(!( fullText.charAt(ss-1).match(/\W/gi) || fullText.charAt(ss).match(/\W/gi) )){
var m = frontText.match(/\W/gi);
if(m){
ss = frontText.lastIndexOf(m[m.length-1])+1;
}
else{
ss = 0;
}
m = endText.match(/\W/gi);
if(m){
se += endText.indexOf(m[0]);
}
else{
se = fullText.length;
}
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
selText = fullText.substring(ss,se);
}
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByCursor(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByLine(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
if(this.byBlock){
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
else{
se = ss;
}
}
if(ss===0 && (se===0 || se == fullText.length) ){
var m=fullText.match(/(\n|\r)/g);
if(m){
se = fullText.indexOf(m[0]);
}else{
se = fullText.length;
}
selText = fullText.substring(0, se);
endText = fullText.substring(se, fullText.length);
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
m = frontText.match(/(\n|\r)/g);
if(m){
ss = frontText.lastIndexOf(m[m.length-1])+1;
}
else{
ss = 0;
}
m = endText.match(/(\n|\r)/g);
if(m){
se += endText.indexOf(m[0]);
}
else{
se = fullText.length;
}
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
if(this.byBlock){
if( (frontText.charAt(frontText.length-1)!='\n') && ss>0 ){
repText = '\n' + repText;
}
if( (endText.charAt(0)!='\n') || se==fullText.length){
repText += '\n';
}
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByTableCell(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(ss===0 || ss==fullText.length){
throw 'not valid cell!';
}
se=ss;
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
i=frontText.lastIndexOf('\n');
j=frontText.lastIndexOf('|');
if(i>j || j<0){
throw 'not valid cell!';
}
ss = j+1;
i=endText.indexOf('\n');
j=endText.indexOf('|');
if(i<j || j<0){
throw 'not valid cell!';
}
se += j;
frontText = fullText.substring(0, ss-1);
selText = fullText.substring(ss,se);
endText = fullText.substring(se+1, fullText.length);
if(this.key.substring(0,5)=='align'){
selText = selText.trim();
if( selText=='>' || selText=='~' || selText.substring(0,8)=='bgcolor(') {return; }
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length - 2;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editSelectAll(param){
var editor = param.button.editor;
editor.selectionStart = 0;
editor.selectionEnd = editor.value.length;
editor.scrollTop = 0;
editor.focus();
}
function wikibar_doPreview(param){
var theButton = param.button;
var editor = param.button.editor;
var wikibar = theButton.parentNode;
if(!wikibar) { return; }
title = theButton.tiddlerTitle;
var editorWrapper = wikibar_resolveTiddlerEditorWrapper(editor);
var tiddlerWrapper = editorWrapper.parentNode;
var previewer = document.getElementById('previewer'+title);
if(previewer){
previewer.parentNode.removeChild(previewer);
editorWrapper.style.display = 'block';
visible=true;
}else{
previewer = document.createElement('div');
previewer.id = 'previewer'+title;
previewer.className = 'viewer previewer';
previewer.style.height = (editor.offsetHeight) + 'px';
wikify(editor.value, previewer);
tiddlerWrapper.insertBefore(previewer, editorWrapper);
editorWrapper.style.display = 'none';
visible=false;
}
var pv=null;
for(var i=0; i<wikibar.childNodes.length; i++){
try{
var btn = wikibar.childNodes[i];
if(btn.toolItem.key == 'preview'){ pv=btn; }
if(btn.toolItem.key != 'preview'){
btn.style.display = visible ? '': 'none';
}
}catch(ex){}
}
if(!pv) { return; }
if(visible){
pv.innerHTML = '<font face=\"verdana\">∞</font>';
pv.title = 'preview current tiddler';
}
else{
pv.innerHTML = '<font face=\"verdana\">←</font>';
pv.title = 'back to editor';
}
}
function wikibar_doListAddons(param){
clearMessage();
var title = param.button.tiddlerTitle;
var wikibarButton = document.getElementById('wikibarButton'+title);
var ok=0, fail=0;
for(var i=0; i<wikibarButton.addons.length; i++){
var addon=wikibarButton.addons[i];
if(addon.ok){
displayMessage('[ o ] '+addon.name);
ok++;
}
else{
displayMessage('[ x ] '+addon.name + ': ' + addon.error);
fail++;
}
}
displayMessage('---------------------------------');
displayMessage(ok + ' ok ; ' + fail + ' failed');
}
function wikibar_getColorCode(param){
var cbOnPickColor = function(colorCode, param){
param.params = colorCode;
param.button.toolItem.doMore(param);
};
wikibarColorTool.openColorPicker(param.button, cbOnPickColor, param);
}
function wikibar_getLinkUrl(param){
var url= prompt('Please enter the link target', (this.param? this.param : ''));
if (url && url.trim().length>0){
param.params = url;
this.doMore(param);
}
}
function wikibar_getTableRowCol(param){
var rc= prompt('Please enter (rows x cols) of the table', '2 x 3');
if (!rc || (rc.trim()).length<=0){ return; }
var arr = rc.toUpperCase().split('X');
if(arr.length != 2) { return; }
for(var i=0; i<arr.length; i++){
if(isNaN(arr[i].trim())) { return; }
}
var rows = parseInt(arr[0].trim(), 10);
var cols = parseInt(arr[1].trim(), 10);
var txtTable='';
for(var r=0; r<rows; r++){
for(var c=0; c<=cols; c++){
if(c===0){
txtTable += '|';
}else{
txtTable += ' |';
}
}
txtTable += '\n';
}
if(txtTable.trim().length>0){
param.params = txtTable.trim();
this.doMore(param);
}
}
function wikibar_getMacroParam(param){
var p = prompt('Please enter the parameters of macro \"' + this.key + '\":' +
'\nSyntax: ' + this.syntax +
'\n\nNote: '+
'\n%1,%2,... - parameter needed'+
'\n[%1] - optional parameter'+
'\n%N - more than one parameter(1~n)'+
'\n[%N] - any number of parameters(0~n)'+
'\n\nPS:'+
'\n1. Parameters should be seperated with space character'+
'\n2. Use \" to wrap the parameter that includes space character, ex: \"hello world\"'+
'\n3. Input the word(null) for the optional parameter ignored',
(this.param? this.param : '') );
if(!p) { return; }
p=p.readMacroParams();
for(var i=0; i<p.length; i++){
var s=p[i].trim();
if(s.indexOf(' ')>0){ p[i]="'"+s+"'"; }
if(s.toLowerCase()=='null'){ p[i]=null; }
}
param.params = p;
this.doMore(param);
}
function wikibar_getMorePalette(unused){
clearMessage();
displayMessage('Get more color palettes(*.gpl) from ColorZilla Palettes site', 'http:\/\/www.iosart.com/firefox/colorzilla/palettes.html');
displayMessage('Save it as a new tiddler with \"ColorPalettes\" tag');
}
function wikibar_createWikibar(title){
var theWikibar = document.getElementById('wikibar' + title);
if(theWikibar){
if(theWikibar.hasChildNodes()){
theWikibar.style.display = (theWikibar.style.display=='block'? 'none':'block');
return;
}
}
var tiddlerWrapper = document.getElementById('tiddler'+title);
var theTextarea = wikibar_resolveTiddlerEditor(tiddlerWrapper);
if(!theTextarea){
clearMessage();
displayMessage('WikiBar only works in tiddler edit mode now');
return;
}else{
if(!theTextarea.id){ theTextarea.id = 'editor'+title; }
if(!theTextarea.parentNode.id){ theTextarea.parentNode.id='editorWrapper'+title; }
}
if(theWikibar){
theWikibar = document.getElementById('wikibar'+title);
}else{
var editorWrapper = wikibar_resolveTiddlerEditorWrapper(theTextarea);
theWikibar = createTiddlyElement(tiddlerWrapper, 'div', 'wikibar'+title, 'toolbar');
addClass(theWikibar, 'wikibar');
var previewer = document.getElementById('previewer'+title);
if(previewer){
tiddlerWrapper.insertBefore(theWikibar, previewer);
}else{
tiddlerWrapper.insertBefore(theWikibar, editorWrapper);
}
}
wikibar_createMenu(theWikibar,wikibarStore,title,theTextarea);
if(config.options['chkWikibarSetEditorHeight'] && config.options['txtWikibarEditorRows']){
theTextarea.rows = config.options['txtWikibarEditorRows'];
}
setStylesheet(
'.wikibar{text-align:left;visibility:visible;margin:2px;padding:1px;}.previewer{overflow:auto;display:block;border:1px solid;}#colorPicker{position:absolute;display:none;z-index:10;margin:0px;padding:0px;}#colorPicker table{margin:0px;padding:0px;border:2px solid #000;border-spacing:0px;border-collapse:collapse;}#colorPicker td{margin:0px;padding:0px;border:1px solid;font-size:11px;text-align:center;cursor:auto;}#colorPicker .header{background-color:#fff;}#colorPicker .button{background-color:#fff;cursor:pointer;cursor:hand;}#colorPicker .button:hover{padding-top:3px;padding-bottom:3px;color:#fff;background-color:#136;}#colorPicker .cell{padding:4px;font-size:7px;cursor:crosshair;}#colorPicker .cell:hover{padding:10px;}.wikibarPopup{position:absolute;z-index:10;border:1px solid #014;color:#014;background-color:#cef;}.wikibarPopup table{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;}.wikibarPopup .button:hover{color:#eee;background-color:#014;}.wikibarPopup .disabled{color:#888;}.wikibarPopup .disabled:hover{color:#888;background-color:#cef;}.wikibarPopup tr .seperator hr{margin:0;padding:0;background-color:#cef;width:100%;border:0;border-top:1px dashed #014;}.wikibarPopup tr .icon{font-family:verdana;font-weight:bolder;}.wikibarPopup tr .marker{font-family:verdana;font-weight:bolder;}.wikibarPopup td{font-size:0.9em;padding:2px;}.wikibarPopup input{border:0;border-bottom:1px solid #014;margin:0;padding:0;font-family:arial;font-size:100%;background-color:#fff;}',
'WikiBarStyleSheet');
}
function wikibar_createMenu(place,toolset,title,editor){
if(!wikibar_isValidMenuItem(toolset)){return;}
if(!(toolset.TYPE=='MAIN_MENU' || toolset.TYPE=='MENU')){ return; }
for(var key in toolset){
if(key.substring(0,9)=='SEPERATOR'){
wikibar_createMenuSeperator(place);
continue;
}
if(key.substring(0,8)=='DYNAITEM'){
var dynaTools = toolset[key](title,editor);
if(dynaTools.TYPE && dynaTools.TYPE=='MENU'){
wikibar_createMenuItem(place,dynaTools,null,editor,title);
}else{
dynaTools.TYPE = 'MENU';
wikibar_createMenu(place, dynaTools, title, editor);
}
continue;
}
if((toolset[key].TYPE!='MENU' && toolset[key].TYPE!='MAIN_MENU') && !toolset[key].HANDLER){continue;}
wikibar_createMenuItem(place,toolset,key,editor,title);
}
}
function wikibar_createMenuItem(place,toolset,key,editor,title){
if(!key){
var tool = toolset;
}else{
tool = toolset[key];
tool.key = key;
}
if(!wikibar_isValidMenuItem(tool)){return;}
var toolIsOnMainMenu = (toolset.TYPE=='MAIN_MENU');
var toolIsMenu = (tool.TYPE=='MENU');
var theButton;
if(toolIsOnMainMenu){
theButton = createTiddlyButton(
place,
'',
(tool.TOOLTIP? tool.TOOLTIP : ''),
(toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem),
'button');
theButton.innerHTML = (tool.CAPTION? tool.CAPTION : key);
theButton.isOnMainMenu = true;
addClass(theButton, (toolIsMenu? 'menu' : 'item'));
place.appendChild( document.createTextNode('\n') );
if(!toolIsMenu){
if(config.options['chkWikibarPopmenuOnMouseOver']){
theButton.onmouseover = function(e){ wikibarPopup.remove(); };
}
}
}else{
theButton=createTiddlyElement(place, 'tr',key,'button');
theButton.title = (tool.TOOLTIP? tool.TOOLTIP : '');
theButton.onclick = (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem);
var tdL = createTiddlyElement(theButton, 'td','','marker');
var td = createTiddlyElement(theButton, 'td');
var tdR = createTiddlyElement(theButton, 'td','','marker');
td.innerHTML = (tool.CAPTION? tool.CAPTION : key);
if(toolIsMenu){
tdR.innerHTML=' ›';
}
if(tool.SELECTED){
tdL.innerHTML = '√ ';
addClass(theButton, 'selected');
}
if(tool.DISABLED){
addClass(theButton, 'disabled');
}
}
theButton.tiddlerTitle = title;
theButton.toolItem = tool;
theButton.editor = editor;
theButton.tabIndex = 999;
if(toolIsMenu){
if(config.options['chkWikibarPopmenuOnMouseOver']){
theButton.onmouseover = wikibar_onClickMenuItem;
}
}
}
function wikibar_createMenuSeperator(place){
if(place.id.substring(0,7)=='wikibar') { return; }
var onclickSeperator=function(e){
if(!e){ e = window.event; }
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return(false);
};
var theButton=createTiddlyElement(place,'tr','','seperator');
var td = createTiddlyElement(theButton, 'td','','seperator');
td.colSpan=3;
theButton.onclick=onclickSeperator;
td.innerHTML = '<hr>';
}
function wikibar_genWikibarAbout(){
var toolset={};
toolset.version = {
CAPTION: '<center>WikiBar ' +
config.macros.wikibar.major + '.' +
config.macros.wikibar.minor + '.' +
config.macros.wikibar.revision +
(config.macros.wikibar.beta? ' beta '+config.macros.wikibar.beta : '') +
'</center>',
HANDLER: function(){}
};
toolset.SEPERATOR = {};
toolset.author = {
CAPTION: '<center>Arphen Lin<br>arphenlin@gmail.com</center>',
TOOLTIP: 'send mail to the author',
HANDLER: function(){ window.open('mailto:arphenlin@gmail.com'); }
};
toolset.website = {
CAPTION: '<center>aiddlywiki.sourceforge.net</center>',
TOOLTIP: 'go to the web site of WikiBar',
HANDLER: function(){ window.open('http:\/\/aiddlywiki.sourceforge.net/'); }
};
return toolset;
}
function wikibar_genWikibarOptions(title, editor){
var toolset={};
toolset.popOnMouseOver = {
CAPTION:'popup menu on mouse over',
SELECTED: config.options['chkWikibarPopmenuOnMouseOver'],
HANDLER: function(param){
config.options['chkWikibarPopmenuOnMouseOver'] = !config.options['chkWikibarPopmenuOnMouseOver'];
saveOptionCookie('chkWikibarPopmenuOnMouseOver');
var title = param.button.tiddlerTitle;
var wikibar = document.getElementById('wikibar'+title);
if(wikibar){ wikibar.parentNode.removeChild(wikibar); }
wikibar_createWikibar(title);
}
};
toolset.setEditorSize = {
CAPTION:'set editor height: <input id=\"txtWikibarEditorRows\" type=text size=1 MAXLENGTH=3 value=\"' +
(config.options['txtWikibarEditorRows']? config.options['txtWikibarEditorRows']:editor.rows) + '\"> ok',
HANDLER: function(param){
var input = document.getElementById('txtWikibarEditorRows');
if(input){
var rows = parseInt(input.value, 10);
if(!isNaN(rows)){
var editor = param.button.editor;
editor.rows = rows;
}else{
rows=config.maxEditRows;
}
config.options['txtWikibarEditorRows'] = rows;
saveOptionCookie('txtWikibarEditorRows');
config.maxEditRows = rows;
}
}
};
toolset.setEditorSizeOnLoadingWikibar = {
CAPTION:'set editor height on loading wikibar',
SELECTED: config.options['chkWikibarSetEditorHeight'],
HANDLER: function(param){
config.options['chkWikibarSetEditorHeight'] = !config.options['chkWikibarSetEditorHeight'];
saveOptionCookie('chkWikibarSetEditorHeight');
if(config.options['chkWikibarSetEditorHeight']){
var rows = config.options['txtWikibarEditorRows'];
if(!isNaN(rows)){ rows = 15; }
var editor = param.button.editor;
editor.rows = rows;
config.options['txtWikibarEditorRows'] = rows;
saveOptionCookie('txtWikibarEditorRows');
}
}
};
toolset.SEPERATOR = {};
toolset.update = {
CAPTION: 'check for updates',
DISABLED: true,
HANDLER: function(){}
};
return toolset;
}
function wikibar_genPaletteSelector(){
try{
var cpTiddlers = store.getTaggedTiddlers('ColorPalettes');
if(!cpTiddlers) { return; }
var palettes=[];
palettes.push(wikibarColorTool.defaultPaletteName);
for(var i=0; i<cpTiddlers.length; i++){
palettes.push(cpTiddlers[i].title.trim());
}
var toolset={};
for(i=0; i<palettes.length; i++){
toolset[palettes[i]] = {
TOOLTIP: palettes[i],
SELECTED: (palettes[i]==wikibarColorTool.paletteName),
HANDLER: wikibar_doSelectPalette
};
}
return toolset;
}catch(ex){ return null; }
}
function wikibar_onClickItem(e){
if(!e){ e = window.event; }
var theTarget = resolveTarget(e);
if(theTarget.tagName=='INPUT'){
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return;
}
var theButton = wikibar_resolveTargetButton(theTarget);
if(!theButton){ return(false); }
var o = theButton.toolItem;
if(!o) { return; }
var param = {
event: e,
button: theButton
};
if(o.HANDLER){ o.HANDLER(param); }
if(o.DISABLED){
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
}
return(false);
}
function wikibar_onClickMenuItem(e){
if(!e){ e = window.event; }
var theButton = wikibar_resolveTargetButton(resolveTarget(e));
if(!theButton){ return(false); }
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
var title = theButton.tiddlerTitle;
var editor = theButton.editor;
var tool = theButton.toolItem;
if(!tool) { return; }
var popup = wikibarPopup.create(this);
if(popup){
wikibar_createMenu(popup,tool,title,editor);
if(!popup.hasChildNodes()){
wikibarPopup.remove();
}else{
wikibarPopup.show(popup, false);
}
}
return(false);
}
var wikibarColorTool = {
defaultPaletteName : 'default',
defaultColumns : 16,
defaultPalette : [
'#FFF','#DDD','#CCC','#BBB','#AAA','#999','#666','#333','#111','#000','#FC0','#F90','#F60','#F30','#C30','#C03',
'#9C0','#9D0','#9E0','#E90','#D90','#C90','#FC3','#FC6','#F96','#F63','#600','#900','#C00','#F00','#F36','#F03',
'#CF0','#CF3','#330','#660','#990','#CC0','#FF0','#C93','#C63','#300','#933','#C33','#F33','#C36','#F69','#F06',
'#9F0','#CF6','#9C3','#663','#993','#CC3','#FF3','#960','#930','#633','#C66','#F66','#903','#C39','#F6C','#F09',
'#6F0','#9F6','#6C3','#690','#996','#CC6','#FF6','#963','#630','#966','#F99','#F39','#C06','#906','#F3C','#F0C',
'#3F0','#6F3','#390','#6C0','#9F3','#CC9','#FF9','#C96','#C60','#C99','#F9C','#C69','#936','#603','#C09','#303',
'#0C0','#3C0','#360','#693','#9C6','#CF9','#FFC','#FC9','#F93','#FCC','#C9C','#969','#939','#909','#636','#606',
'#060','#3C3','#6C6','#0F0','#3F3','#6F6','#9F9','#CFC','#9CF','#FCF','#F9F','#F6F','#F3F','#F0F','#C6C','#C3C',
'#030','#363','#090','#393','#696','#9C9','#CFF','#39F','#69C','#CCF','#C9F','#96C','#639','#306','#90C','#C0C',
'#0F3','#0C3','#063','#396','#6C9','#9FC','#9CC','#06C','#369','#99F','#99C','#93F','#60C','#609','#C3F','#C0F',
'#0F6','#3F6','#093','#0C6','#3F9','#9FF','#699','#036','#039','#66F','#66C','#669','#309','#93C','#C6F','#90F',
'#0F9','#6F9','#3C6','#096','#6FF','#6CC','#366','#069','#36C','#33F','#33C','#339','#336','#63C','#96F','#60F',
'#0FC','#6FC','#3C9','#3FF','#3CC','#399','#033','#39C','#69F','#00F','#00C','#009','#006','#003','#63F','#30F',
'#0C9','#3FC','#0FF','#0CC','#099','#066','#3CF','#6CF','#09C','#36F','#0CF','#09F','#06F','#03F','#03C','#30C'
],
colorPicker : null,
pickColorHandler: null,
userData: null
};
wikibarColorTool.paletteName = wikibarColorTool.defaultPaletteName;
wikibarColorTool.columns = wikibarColorTool.defaultColumns;
wikibarColorTool.palette = wikibarColorTool.defaultPalette;
wikibarColorTool.onPickColor = function(e){
if (!e){ e = window.event; }
var theCell = resolveTarget(e);
if(!theCell){ return(false); }
color = theCell.bgColor.toLowerCase();
if(!color) { return; }
wikibarColorTool.displayColorPicker(false);
if(wikibarColorTool.pickColorHandler){
wikibarColorTool.pickColorHandler(color, wikibarColorTool.userData);
}
return(false);
};
wikibarColorTool.onMouseOver = function(e){
if (!e){ e = window.event; }
var theButton = resolveTarget(e);
if(!theButton){ return(false); }
if(!wikibarColorTool) { return; }
color = theButton.bgColor.toUpperCase();
if(!color) { return; }
td=document.getElementById('colorPickerInfo');
if(!td) { return; }
td.bgColor = color;
td.innerHTML = '<span style=\"color:#000;\">'+color+'</span> ' +
'<span style=\"color:#fff;\">'+color+'</span>';
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return(false);
};
wikibarColorTool.openColorPicker = function(theTarget, pickColorHandler, userData){
wikibarColorTool.skipClickDocumentEvent = true;
wikibarColorTool.pickColorHandler = pickColorHandler;
wikibarColorTool.userData = userData;
wikibarColorTool.moveColorPicker(theTarget);
};
wikibarColorTool.convert3to6HexColor = function(c){
c=c.trim();
var rx=/^\#(\d|[a-f])(\d|[a-f])(\d|[a-f])$/gi;
return (rx.test(c)? c.replace(rx, '#$1$1$2$2$3$3') : c);
};
wikibarColorTool.numToHexColor = function (n){
if(typeof(n)=='number' && (n>=0 && n<=255)) {
s = n.toString(16).toLowerCase();
return ((s.length==1)? '0'+s : s);
}else{
return null;
}
};
wikibarColorTool.renderColorPalette = function(){
if(wikibarColorTool.paletteName==wikibarColorTool.defaultPaletteName){
wikibarColorTool.palette=wikibarColorTool.defaultPalette;
wikibarColorTool.columns=wikibarColorTool.defaultColumns;
return;
}
tiddlerText = (store.getTiddlerText(wikibarColorTool.paletteName, '')).trim();
if(tiddlerText.length<=0) { return; }
var cpContents = tiddlerText.split('\n');
var colors=[];
columns = wikibarColorTool.defaultColumns;
var tmpArray=null;
errCount=0;
for(var i=0; i<cpContents.length; i++){
cpLine=cpContents[i].trim();
if( (!cpLine) || (cpLine.length<=0) || (cpLine.charAt(0) == '#') ){ continue; }
if(cpLine.substring(0,8).toLowerCase()=='columns:'){
tmpArray = cpLine.split(':');
try{
columns = parseInt(tmpArray[1],10);
}catch(ex){
columns = wikibarColorTool.defaultColumns;
}
}else{
tmpArray = cpLine.replace('\t', ' ').split(/[ ]{1,}/);
try{
color='';
for(var j=0; j<3; j++){
c=parseInt(tmpArray[j].trim(), 10);
if(isNaN(c)){
break;
}else{
c=wikibarColorTool.numToHexColor(c);
if(!c) {break;}
color+=c;
}
}
if(color.length==6){
colors.push('#'+color);
} else {
throw 'error';
}
}catch(ex){
}
}
}
if(colors.length>0){
wikibarColorTool.palette = colors;
wikibarColorTool.columns = columns;
}else{
throw 'renderColorPalette(): No color defined in the palette.';
}
};
wikibarColorTool.displayColorPicker = function(visible){
if(wikibarColorTool.colorPicker){
wikibarColorTool.colorPicker.style.display = (visible? 'block' : 'none');
}
};
wikibarColorTool.moveColorPicker = function(theTarget){
if(!wikibarColorTool.colorPicker){
wikibarColorTool.createColorPicker();
}
var cp = wikibarColorTool.colorPicker;
var rootLeft = findPosX(theTarget);
var rootTop = findPosY(theTarget);
var popupLeft = rootLeft;
var popupTop = rootTop;
var popupWidth = cp.offsetWidth;
var winWidth = findWindowWidth();
if(popupLeft + popupWidth > winWidth){
popupLeft = winWidth - popupWidth;
}
cp.style.left = popupLeft + 'px';
cp.style.top = popupTop + 'px';
wikibarColorTool.displayColorPicker(true);
};
wikibarColorTool.createColorPicker = function(unused, palette){
if(palette){ wikibarColorTool.paletteName=palette; }
wikibarColorTool.renderColorPalette();
wikibarColorTool.colorPicker = document.createElement('div');
wikibarColorTool.colorPicker.id = 'colorPicker';
document.body.appendChild(wikibarColorTool.colorPicker);
var theTable = document.createElement('table');
wikibarColorTool.colorPicker.appendChild(theTable);
var theTR = document.createElement('tr');
theTable.appendChild(theTR);
var theTD = document.createElement('td');
theTD.className = 'header';
theTD.colSpan = wikibarColorTool.columns;
theTD.innerHTML = wikibarColorTool.paletteName;
theTR.appendChild(theTD);
for(var i=0; i<wikibarColorTool.palette.length; i++){
if((i%wikibarColorTool.columns)===0){
theTR = document.createElement('tr');
theTable.appendChild(theTR);
}
theTD = document.createElement('td');
theTD.className = 'cell';
theTD.bgColor = wikibarColorTool.convert3to6HexColor(wikibarColorTool.palette[i]);
theTD.onclick = wikibarColorTool.onPickColor;
theTD.onmouseover = wikibarColorTool.onMouseOver;
theTR.appendChild(theTD);
}
rest = wikibarColorTool.palette.length % wikibarColorTool.columns;
if(rest>0){
theTD = document.createElement('td');
theTD.colSpan = wikibarColorTool.columns-rest;
theTD.bgColor = '#000000';
theTR.appendChild(theTD);
}
theTR = document.createElement('tr');
theTable.appendChild(theTR);
theTD = document.createElement('td');
theTD.colSpan = wikibarColorTool.columns;
theTD.id = 'colorPickerInfo';
theTR.appendChild(theTD);
};
wikibarColorTool.onDocumentClick = function(e){
if (!e){ e = window.event; }
if(wikibarColorTool.skipClickDocumentEvent) {
wikibarColorTool.skipClickDocumentEvent = false;
return true;
}
if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
wikibarColorTool.displayColorPicker(false);
}
return true;
};
function wikibar_doSelectPalette(param){
clearMessage();
var theButton = param.button;
if(!theButton.toolItem.key) { return; }
var palette = theButton.toolItem.key;
var oldPaletteName = wikibarColorTool.paletteName;
if(oldPaletteName != palette){
try{
wikibarColorTool.createColorPicker(theButton, palette);
displayMessage('Palette \"'+palette+'\" ('+ wikibarColorTool.palette.length +' colors) is selected');
}catch(ex){
errMsg = ex;
if(errMsg.substring(0,18)=='renderColorPalette'){
displayMessage('Invalid palette \"' + palette + '\", please check it out!');
wikibarColorTool.createColorPicker(theButton, oldPaletteName);
}
}
}
}
var wikibarPopup = {
skipClickDocumentEvent: false,
stack: []
};
wikibarPopup.resolveRootPopup = function(o){
if(o.isOnMainMenu){ return null; }
if(o.className.substring(0,12)=='wikibarPopup'){ return o;}
return wikibarPopup.resolveRootPopup(o.parentNode);
};
wikibarPopup.create = function(root){
for(var i=0; i<wikibarPopup.stack.length; i++){
var p=wikibarPopup.stack[i];
if(p.root==root){
wikibarPopup.removeFrom(i+1);
return null;
}
}
var rootPopup = wikibarPopup.resolveRootPopup(root);
if(!rootPopup){
wikibarPopup.remove();
}else{
wikibarPopup.removeFromRootPopup(rootPopup);
}
var popup = createTiddlyElement(document.body,'div','wikibarPopup'+root.toolItem.key,'wikibarPopup');
var pop = createTiddlyElement(popup,'table','','');
wikibarPopup.stack.push({rootPopup: rootPopup, root: root, popup: popup});
return pop;
};
wikibarPopup.show = function(unused,slowly){
var curr = wikibarPopup.stack[wikibarPopup.stack.length-1];
var overlayWidth = 1;
var rootLeft, rootTop, rootWidth, rootHeight, popupLeft, popupTop, popupWidth;
if(curr.rootPopup){
rootLeft = findPosX(curr.rootPopup);
rootTop = findPosY(curr.root);
rootWidth = curr.rootPopup.offsetWidth;
popupLeft = rootLeft + rootWidth - overlayWidth;
popupTop = rootTop;
}else{
rootLeft = findPosX(curr.root);
rootTop = findPosY(curr.root);
rootHeight = curr.root.offsetHeight;
popupLeft = rootLeft;
popupTop = rootTop + rootHeight;
}
var winWidth = findWindowWidth();
popupWidth = curr.popup.offsetWidth;
if(popupLeft + popupWidth > winWidth){
popupLeft = rootLeft - popupWidth + overlayWidth;
}
curr.popup.style.left = popupLeft + 'px';
curr.popup.style.top = popupTop + 'px';
curr.popup.style.display = 'block';
addClass(curr.root, 'highlight');
if(config.options.chkAnimate){
anim.startAnimating(new Scroller(curr.popup,slowly));
}else{
window.scrollTo(0,ensureVisible(curr.popup));
}
};
wikibarPopup.remove = function(){
if(wikibarPopup.stack.length > 0){
wikibarPopup.removeFrom(0);
}
};
wikibarPopup.removeFrom = function(from){
for(var t=wikibarPopup.stack.length-1; t>=from; t--){
var p = wikibarPopup.stack[t];
removeClass(p.root,'highlight');
p.popup.parentNode.removeChild(p.popup);
}
wikibarPopup.stack = wikibarPopup.stack.slice(0,from);
};
wikibarPopup.removeFromRootPopup = function(from){
for(var t=0; t<wikibarPopup.stack.length; t++){
var p = wikibarPopup.stack[t];
if(p.rootPopup==from){
wikibarPopup.removeFrom(t);
break;
}
}
};
wikibarPopup.onDocumentClick = function(e){
if (!e){ e = window.event; }
if(wikibarPopup.skipClickDocumentEvent){
wikibarPopup.skipClickDocumentEvent=false;
return true;
}
if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
wikibarPopup.remove();
}
return true;
};
var wikibarStore = {
TYPE: 'MAIN_MENU',
help:{
TYPE:'MENU',
CAPTION: '<font face=\"verdana\">?</font>',
TOOLTIP: 'about WikiBar',
options:{
TYPE:'MENU',
DYNAITEM: wikibar_genWikibarOptions
},
about:{
TYPE:'MENU',
DYNAITEM: wikibar_genWikibarAbout
}
},
preview:{
TOOLTIP: 'preview this tiddler',
CAPTION: '<font face=\"verdana\">∞</font>',
HANDLER: wikibar_doPreview
},
line:{
TOOLTIP: 'horizontal line',
CAPTION: '<font face=\"verdana\">—</font>',
syntax: '\n----\n',
HANDLER: wikibar_editFormatByCursor
},
crlf:{
TOOLTIP: 'new line',
CAPTION: '<font face=\"verdana\">¶</font>',
syntax: '\n',
HANDLER: wikibar_editFormatByCursor
},
selectAll:{
TOOLTIP: 'select all',
CAPTION: '<font face=\"verdana\">§</font>',
HANDLER: wikibar_editSelectAll
},
deleteSelected:{
TOOLTIP: 'delete selected',
CAPTION: '<font face=\"verdana\">×</font>',
syntax: '',
HANDLER: wikibar_editFormat
},
textFormat:{
TYPE: 'MENU',
CAPTION: 'text',
TOOLTIP: 'text formatters',
ignore:{
TOOLTIP: 'ignore wiki word',
CAPTION: 'ignore wikiWord',
syntax: '~user_text',
hint: 'wiki_word',
HANDLER: wikibar_editFormatByWord
},
bolder:{
TOOLTIP: 'bolder text',
CAPTION: '<strong>bolder</strong>',
syntax: "''user_text''",
hint: 'bold_text',
HANDLER: wikibar_editFormatByWord
},
italic:{
TOOLTIP: 'italic text',
CAPTION: '<em>italic</em>',
syntax: '\/\/user_text\/\/',
hint: 'italic_text',
HANDLER: wikibar_editFormatByWord
},
underline:{
TOOLTIP: 'underline text',
CAPTION: '<u>underline</u>',
syntax: '__user_text__',
hint: 'underline_text',
HANDLER: wikibar_editFormatByWord
},
strikethrough:{
TOOLTIP: 'strikethrough text',
CAPTION: '<strike>strikethrough</strike>',
syntax: '==user_text==',
hint: 'strikethrough_text',
HANDLER: wikibar_editFormatByWord
},
superscript:{
TOOLTIP: 'superscript text',
CAPTION: 'X<sup>superscript</sup>',
syntax: '^^user_text^^',
hint: 'superscript_text',
HANDLER: wikibar_editFormatByWord
},
subscript:{
TOOLTIP: 'subscript text',
CAPTION: 'X<sub>subscript</sub>',
syntax: '~~user_text~~',
hint: 'subscript_text',
HANDLER: wikibar_editFormatByWord
},
comment:{
TOOLTIP: 'comment text',
CAPTION: 'comment text',
syntax: '/%user_text%/',
hint: 'comment_text',
HANDLER: wikibar_editFormatByWord
},
monospaced:{
TOOLTIP: 'monospaced text',
CAPTION: '<code>monospaced</code>',
syntax: '{{{user_text}}}',
hint: 'monospaced_text',
HANDLER: wikibar_editFormatByWord
}
},
paragraph:{
TYPE: 'MENU',
TOOLTIP: 'paragarph formatters',
list:{
TYPE: 'MENU',
TOOLTIP: 'list tools',
bullet:{
TOOLTIP: 'bullet point',
syntax: '*user_text',
hint: 'bullet_text',
HANDLER: wikibar_editFormatByLine
},
numbered:{
TOOLTIP: 'numbered list',
syntax: '#user_text',
hint: 'numbered_text',
HANDLER: wikibar_editFormatByLine
}
},
heading:{
TYPE: 'MENU',
heading1:{
CAPTION:'<h1>Heading 1</h1>',
TOOLTIP: 'Heading 1',
syntax: '!user_text',
hint: 'heading_1',
HANDLER: wikibar_editFormatByLine
},
heading2:{
CAPTION:'<h2>Heading 2<h2>',
TOOLTIP: 'Heading 2',
syntax: '!!user_text',
hint: 'heading_2',
HANDLER: wikibar_editFormatByLine
},
heading3:{
CAPTION:'<h3>Heading 3</h3>',
TOOLTIP: 'Heading 3',
syntax: '!!!user_text',
hint: 'heading_3',
HANDLER: wikibar_editFormatByLine
},
heading4:{
CAPTION:'<h4>Heading 4</h4>',
TOOLTIP: 'Heading 4',
syntax: '!!!!user_text',
hint: 'heading_4',
HANDLER: wikibar_editFormatByLine
},
heading5:{
CAPTION:'<h5>Heading 5</h5>',
TOOLTIP: 'Heading 5',
syntax: '!!!!!user_text',
hint: 'heading_5',
HANDLER: wikibar_editFormatByLine
}
},
comment:{
TYPE: 'MENU',
commentByLine:{
CAPTION:'comment by line',
TOOLTIP: 'line comment',
syntax: '/%user_text%/',
hint: 'comment_text',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION:'comment by block',
TOOLTIP: 'block comment',
syntax: '/%\nuser_text\n%/',
hint: 'comment_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
monospaced:{
TYPE: 'MENU',
monosByLine:{
CAPTION: 'monospaced by line',
TOOLTIP: 'line monospaced',
syntax: '{{{\nuser_text\n}}}',
hint: 'monospaced_text',
HANDLER: wikibar_editFormatByLine
},
monosByBlock:{
CAPTION: 'monospaced by block',
TOOLTIP: 'block monospaced',
syntax: '{{{\nuser_text\n}}}',
hint: 'monospaced_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
quote:{
TYPE: 'MENU',
quoteByLine:{
CAPTION: 'quote by line',
TOOLTIP: 'line quote',
syntax: '>user_text',
hint: 'quote_text',
HANDLER: wikibar_editFormatByLine
},
quoteByBlcok:{
CAPTION: 'quote by block',
TOOLTIP: 'block quote',
syntax: '<<<\nuser_text\n<<<',
hint: 'quote_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
plugin:{
TYPE: 'MENU',
code:{
CAPTION: 'code area',
TOOLTIP: 'block monospaced for plugin',
syntax: '\n\/\/{{{\nuser_text\n\/\/}}}\n',
hint: 'monospaced_plugin_code',
byBlock: true,
HANDLER: wikibar_editFormatByLine
},
commentByLine:{
CAPTION: 'comment by line',
TOOLTIP: 'line comment',
syntax: '\/\/user_text',
hint: 'plugin_comment',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION: 'comment by block',
TOOLTIP: 'block comment',
syntax: '\/\***\nuser_text\n***\/',
hint: 'plugin_comment',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
css:{
TYPE: 'MENU',
code:{
CAPTION: 'code area',
TOOLTIP: 'block monospaced for css',
syntax: '\n\nuser_text\n\n',
hint: 'monospaced_css_code',
byBlock: true,
HANDLER: wikibar_editFormatByLine
},
commentByLine:{
CAPTION: 'comment by line',
TOOLTIP: 'line comment',
syntax: '',
hint: 'css_comment',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION: 'comment by block',
TOOLTIP: 'block comment',
syntax: '',
hint: 'css_comment',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
}
},
color:{
TYPE: 'MENU',
TOOLTIP: 'color tools',
highlight:{
CAPTION:'highlight text',
TOOLTIP: 'highlight text',
syntax: '@@user_text@@',
hint: 'highlight_text',
HANDLER: wikibar_editFormatByWord
},
color:{
CAPTION:'text color',
TOOLTIP: 'text color',
hint: 'your_text',
syntax: '@@color(%1):user_text@@',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByWord
},
bgcolor:{
CAPTION:'background color',
TOOLTIP: 'background color',
hint: 'your_text',
syntax: '@@bgcolor(%1):user_text@@',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByWord
},
colorcode:{
CAPTION:'color code',
TOOLTIP: 'insert color code',
syntax: '%1',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByCursor
},
'color palette':{
TYPE:'MENU',
DYNAITEM: wikibar_genPaletteSelector,
SEPERATOR:{},
morePalette:{
CAPTION:'more palettes',
TOOLTIP:'get more palettes',
HANDLER: wikibar_getMorePalette
}
}
},
link:{
TYPE: 'MENU',
TOOLTIP: 'insert link',
wiki:{
CAPTION:'wiki link',
TOOLTIP: 'wiki link',
syntax: '[[user_text]]',
hint: 'wiki_word',
HANDLER: wikibar_editFormatByWord
},
pretty:{
CAPTION: 'pretty link',
TOOLTIP: 'pretty link',
syntax: '[[user_text|%1]]',
hint: 'pretty_word',
param: 'PrettyLink Target',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
},
url:{
TOOLTIP: 'url link',
syntax: '[[user_text|%1]]',
hint: 'your_text',
param: 'http:\/\/...',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
},
image:{
TOOLTIP: 'image link',
syntax: '[img[user_text|%1]]',
hint: 'alt_text',
param: 'image/icon.jpg',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
}
},
macro:{},
more:{
TYPE: 'MENU',
TOOLTIP: 'more tools',
table:{
TYPE: 'MENU',
TOOLTIP: 'table',
table:{
CAPTION:'create table',
TOOLTIP: 'create a new table',
syntax: '\n%1\n',
HANDLER: wikibar_getTableRowCol,
doMore: wikibar_editFormatByWord
},
header:{
TOOLTIP: 'table header text',
syntax: '|user_text|c',
hint: 'table_header',
HANDLER: wikibar_editFormatByWord
},
cell:{
TOOLTIP: 'create a tabel cell',
syntax: '|user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByWord
},
columnHeader:{
CAPTION:'column header',
TOOLTIP: 'create a column header cell',
syntax: '|!user_text|',
hint: 'column_header',
HANDLER: wikibar_editFormatByWord
},
cell:{
TYPE: 'MENU',
CAPTION: 'cell options',
bgcolor:{
CAPTION: 'background color',
TOOLTIP: 'cell bgcolor',
syntax: '|bgcolor(%1):user_text|',
hint: 'your_text',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByTableCell
},
alignLeft:{
CAPTION: 'align left',
TOOLTIP: 'left align cell text',
syntax: '|user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
},
alignCenter:{
CAPTION: 'align center',
TOOLTIP: 'center align cell text',
syntax: '| user_text |',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
},
alignRight:{
CAPTION: 'align right',
TOOLTIP: 'right align cell text',
syntax: '| user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
}
}
},
html:{
TYPE: 'MENU',
html:{
CAPTION: '<html>',
TOOLTIP: 'html tag',
syntax: '<html>\nuser_text\n</html>',
hint: 'html_content',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
}
},
addon:{
TYPE: 'MENU',
TOOLTIP:'3rd party tools',
'about addons':{
TOOLTIP: 'list loaded addons',
HANDLER: wikibar_doListAddons
},
SEPERATOR:{}
}
};
addEvent(document, 'click', wikibarColorTool.onDocumentClick);
addEvent(document, 'click', wikibarPopup.onDocumentClick);
wikibar_install();
//}}}
For YourSearchPlugin source code see the [[archive|http://tiddlywiki.abego-software.de/archive]].
/***
This patches should be executed after their original plugins has been loaded
***/
//{{{
//hacking taggerPlugin externally to remove excluded tags from the list
if (config.macros.tagger) window.eval(store.getTiddlerText("TaggerPlugin").replace(/store.getTags\(\);/,"store.getTags('excludeLists');"));
//}}}
//{{{
//hacking LessBackupsPlugin externally to change configuration without editing the plugin code
if (window.getSpecialBackupPath) {
window.getBackupModes = [
["ddd", 7*24*60*60*1000], // one per weekday
["latest",0] // always keep last version. (leave this).
];
window.eval(store.getTiddlerText("LessBackupsPlugin").match(/window.getSpecialBackupPath =(.*)\n(.*\n)*(?:\/\/ hijack)/m)[0].replace(/var now /,"var modes = window.getBackupModes;\nvar now "));
}
//}}}