Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
replace this content with information about ''your'' blog
{{small{<<slider
{{config.options.chkOpenedSlider=false;"chkOpenedSlider";}}
AddANote##sliderSection
"add a note..."
{{"add a quick note to '"+tiddler.title+"'"}}
>>}}}/%
!sliderSection
<<comment {{tiddler.title}}>>
!end
%/
/***
|Name|AdvancedOptionsPlugin|
|Source|http://www.TiddlyTools.com/#AdvancedOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#AdvancedOptionsPlugin|
|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.3|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|automatically add plugin-defined options to the [[AdvancedOptions]] shadow tiddler|
!!!!!Usage
<<<
At document startup, this plugin examines each tiddler tagged with <<tag systemConfig>> and looks for a tiddler slice named "Options" whose value refers to a tiddler section (or separate tiddler) that contains an 'advanced options control panel' for configuring that plugin's features and behavior. For each plugin that contains an "Options" slice, a tabbed entry is automatically created in the [[AdvancedOptions]] shadow tiddler to display that plugin's control panel.
As an optional fallback for backward-compatibility with plugin tiddlers that do not define the "Options" slice, this plugin will also look for a section heading named "Configuration" within those tiddlers, so that older plugins that define this section can automatically have their settings added to the [[AdvancedOptions]] tiddler without requiring the "Options" slice to be added.
<<<
!!!!!Configuration
<<<
<<option chkAdvancedOptions>> automatically add plugin-defined options to the [[AdvancedOptions]] shadow tiddler
<<option chkAdvancedOptionsBackstage>> automatically add plugin-defined options to Backstage menu
<<option chkAdvancedOptionsFallback>> use <<option txtAdvancedOptionsFallback>> section as a fallback for plugins that don't define an ~AdvancedOptions slice
//note: these settings only take effect after reloading the document//
<<<
!!!!!Revisions
<<<
2008.05.09 [1.1.0] add "options" panel to backstage
2008.04.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.AdvancedOptionsPlugin= {major: 1, minor: 1, revision: 0, date: new Date(2008,5,9)};
if (config.options.chkAdvancedOptions===undefined)
config.options.chkAdvancedOptions=true;
if (config.options.chkAdvancedOptionsBackstage===undefined)
config.options.chkAdvancedOptionsBackstage=true;
if (config.options.chkAdvancedOptionsFallback===undefined)
config.options.chkAdvancedOptionsFallback=true;
if (config.options.txtAdvancedOptionsFallback===undefined)
config.options.txtAdvancedOptionsFallback="Configuration";
if (config.optionsDesc) config.optionsDesc.chkAdvancedOptions=
"automatically add plugin-defined options to [[AdvancedOptions]]";
var items=[];
var fmt="[[%0 ]] [[view options for %0]] [[%1]]\n";
var section=config.options.txtAdvancedOptionsFallback;
var plugins=store.getTaggedTiddlers("systemConfig");
for (var p=0; p<plugins.length; p++) {
var tid=plugins[p].title;
var settings=store.getTiddlerSlice(tid,"Options");
if (!settings && config.options.chkAdvancedOptionsFallback && store.getTiddlerText(tid+"##"+section))
settings="##"+section; // fallback handling for older plugins
if (settings&&settings.length) {
if (settings.substr(0,2)=="##") settings=tid+settings;
items.push(fmt.format([tid,settings]));
}
}
if (items.length) config.shadowTiddlers.PluginOptions=
"!![[Plugin-defined options|PluginManager]]\n>@@text-align:left;<<tabs '' \n"+items.join(' ')+">>@@";
if (config.options.chkAdvancedOptions)
config.shadowTiddlers.AdvancedOptions+="{{smallform{{{wrap{<<tiddler PluginOptions>>}}}}}}";
// add "options" backstage task
if (config.tasks && config.options.chkAdvancedOptionsBackstage) { // for TW2.2b3 or above
config.tasks.options = {
text: "options",
tooltip: "manage plugin-defined option settings",
content: "{{smallform{{{groupbox{{{wrap{<<tiddler PluginOptions>>}}}}}}\n{{groupbox small {<<options>>}}}}}}"
}
config.backstageTasks.splice(config.backstageTasks.indexOf("plugins")+1,0,"options");
}
//}}}
/%
Description: An Invitation from Oriah Mountain Dreamer
%/
<<tiddler HideTiddlerTags>>{{center medium italic{
__An Invitation from Oriah Mountain Dreamer, Indian Elder.__
May 1994
It doesn't interest me what you do for a living.
I want to know what you ache for, and if you dare
to dream of meeting your heart's longing.
It doesn't interest me how old you are.
I want to know if you will risk looking like a fool for love,
for your dreams, for the adventure of being alive.
It doesn't interest me what planets are squaring your moon.
I want to know if you have touched the center of your own sorrow,
if you have been opened by life's betrayals or have become
shriveled and closed from fear of further pain!
I want to know if you can sit with pain, mine or your own,
without moving to hide it or fade it or fix it.
I want to know if you can be with JOY, mine or your own;
if you can dance with wildness and let the ecstasy
fill you to the tips of your fingers and toes
without cautioning us to be careful, be realistic,
or to remember the limitations of being a human.
It doesn't interest me if the story you're telling me is true.
I want to know if you can disappoint another
to be true to yourself;
if you can bear the accusation of betrayal
and not betray your own soul.
I want to know if you can be faithful
and therefore be trustworthy.
I want to know if you can see beauty
even when it is not pretty every day,
and if you can source your life from ITS presence.
I want to know if you can live with failure, yours and mine,
and still stand on the edge of a lake
and shout to the silver of the full moon, "YES!"
It doesn't interest me to know where you live
or how much money you have.
I want to know if you can get up
after the night of grief and despair,
weary and bruised to the bone,
and do what needs to be done for the children.
It doesn't interest me who you are, how you came to be here.
I want to know if you will stand in the center of the fire with me
and not shrink back.
It doesn't interest me where or what or with whom you have studied.
I want to know what sustains you from the inside
when all else falls away.
}}}
/%
|Name|AutoRefresh|
|Source|http://www.TiddlyTools.com/#AutoRefresh|
|Version|0.6.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|enable/disable auto-refresh of selected content to force/prevent re-rendering when tiddler changes occur|
usage:
<<tiddler AutoRefresh with: mode id>>
where:
mode - (optional) is one of:
off (or disable) - prevent refresh of rendered content (except when PageTemplate is changed!)
on (or enable)- re-render content whenever corresponding tiddler source is changed
force - re-render content whenever ANY tiddler content is changes (or refreshDisplay() is triggered)
id - (optional)
is a unique DOM element identifier on which to operate.
If not specified, the current tiddler (or containing parent if not in a tiddler) is used.
%/<script>
var here=story.findContainingTiddler(place);
if (here) { // in a tiddler, get containing viewer element
var here=place; while (here && here.className!='viewer') here=here.parentNode;
if (!here) return; // no 'viewer' element (perhaps a custom template?)
}
else here=place.parentNode; // not in a tiddler, use immediate parent container
// if DOM id param, get element by ID instead of using container
if ("$2"!="$"+"2") var here=document.getElementById("$2");
if (!here) return; // safety check
var mode="$1"; if (mode=="$"+"1") mode="on";
switch (mode.toLowerCase()) {
case 'on':
case 'enable':
case 'force':
var title=here.getAttribute("tiddler");
if (!title) { // find source tiddler title
var tid=story.findContainingTiddler(place);
if (!tid) return; // can't determine source tiddler
title=tid.getAttribute("tiddler");
}
here.setAttribute("tiddler",title);
here.setAttribute("refresh","content");
here.setAttribute("force",(mode=='force')?"true":"");
break;
case 'off':
case 'disable':
here.setAttribute("refresh","");
here.setAttribute("force","");
break;
}
</script>
/%
URL: Enter a URL
Description: enter a description
Author: enter author/moderator info
%/
enter your notes here
/%
Description: enter a description here
%/
enter FAQ content here
/%
Description: enter a description here (for display in JournalViewer droplist)
%/$1
enter content here
/%
|Name|BookmarkList|
|Source|http://www.TiddlyTools.com/#BookmarkList|
|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|InlineJavascriptPlugin|
|Overrides||
|Description|generate MiniBrowser-compatible HR-separated list of tiddlers tagged with bookmark|
Usage: <<miniBrowser BookmarkList>>
%/<script>
var out=[];
var tids=store.getTaggedTiddlers("bookmark");
for (var i=0; i<tids.length; i++) {
var t=tids[i].title;
var d=store.getTiddlerSlice(t,"Description");
var u=store.getTiddlerSlice(t,"URL")
out.push("[[%0]] - %1\n%2".format([t,d,u]));
}
return out.join("\n----\n");
</script>
Tiddlers that are tagged with<<tag bookmark>>can be used to define ''~URLs, descriptions and author information for favorite websites''.
Bookmark tiddlers are displayed using a custom BookmarkViewTemplate (requires use of TaggedTemplateTweak), which automatically embeds the website directly in the tiddler content using an HTML "IFRAME" element. Most (but not all) of the bookmarks distributed with this TiddlyTools package refer to TiddlyWiki documents and are also tagged with<<tag systemServer>>, allowing them to be selected as import sources when using the TiddlyWiki standard ImportTiddlers function.
To create additional bookmarks, simply copy the BlankBookmark tiddler, edit the URL, description, and author info, tag the new tiddler with<<tag bookmark>>and press 'done' to start viewing the remote URL. Alternatively, you can add the following """<<newTiddler>>""" macro in your SideBarOptions (or any other tiddler) to insert a<<newTiddler label:'new bookmark' title:'NewBookmark' text:{{store.getTiddlerText('BlankBookmark','')}} tag:'bookmark' prompt:'create a bookmark tiddler'>>command into your document:
{{{
<<newTiddler label:'new bookmark' title:'NewBookmark' tag:'bookmark'
text:{{store.getTiddlerText('BlankBookmark','')}}>>
}}}
<!--{{{-->
<!--
|Name|BookmarkViewTemplate|
|Source|http://www.TiddlyTools.com/#BookmarkViewTemplate|
|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|template|
|Requires|WikifyPlugin, TaggedTemplateTweak|
|Overrides||
|Description|custom template used to display tiddlers tagged with "Bookmark"|
Usage:
Create a tiddler tagged with "bookmark" (or "Bookmark") and enter URL, description and author using a 'slice table':
|URL:|Enter a URL|
|Description:|enter a description|
|Author:|enter author/moderator info|
-->
<span class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></span>
<div class='toolbar' macro='tiddler RefreshCommand'></div>
<span class='title' macro='view title'></span>
<span macro='tiddler AddANote if:{{store.tiddlerExists(story.findContainingTiddler(place).getAttribute("tiddler")) && tiddler && tiddler.tags.containsAny(["annotate", "bookmark", "journal", "blog"])}} with: {{tiddler?tiddler.title:""}}'></span>
<!-- OMIT
<span class='subtitle' style='white-space:nowrap' macro='view modified date [[DDD, MMM DDth YYYY]]'></span>
-->
<div class='tagClear'></div>
<div class='viewer'>
<div class='floatleft' macro='wikify "{{big{[[%0|%1]]}}}<br>" here::Description here::URL'></div>
<div class='toolbar'>
<a class='button' href='javascript:;'
onclick='window.history.go(-1);' title='go back one page'>back</a>
<a class='button' href='javascript:;'
onclick='window.history.go(+1);' title='go foward one page'>forward</a>
<a class='button' href='javascript:;'
onclick='var f=this.parentNode.parentNode.getElementsByTagName("iframe")[0];
f.src=f.src'
title='reload current page'>reload</a>
<a class='button' href='javascript:;'
onclick='var f=this.parentNode.parentNode.getElementsByTagName("iframe")[0];
var w=prompt("Enter a new frame width (use px, em, cm, in, or %)","100%");
if (!w||!w.length) return; if (!w.replace(/[0-9]*/,"").length) w+="px";
f.style.width=w;'
title='set frame width'>width</a>
<a class='button' href='javascript:;'
onclick='var f=this.parentNode.parentNode.getElementsByTagName("iframe")[0];
var h=prompt("Enter a new frame height (use px, em, cm, or in)","500");
if (!h||!h.length) return; if (!h.replace(/[0-9]*/,"").length) h+="px";
f.style.height=h;'
title='set frame height'>height</a>
<a class='button' href='javascript:;'
onclick='var f=this.parentNode.parentNode.getElementsByTagName("iframe")[0];
var show=f.style.display=="none";
f.style.display=show?"block":"none";
this.innerHTML=show?"hide":"show";'
title="toggle display of this frame (but DON'T reload content)">hide</a>
</div><div class='tagClear'
macro='wikify [[<html><iframe src="%0" height="500" width="100%" style="background:#fff"></iframe></html>]] here::URL'>
</div>
<div macro='view text wikified'></div>
</div>
<!--}}}-->
/%
|Name|BreadcrumbsCommand|
|Source|http://www.TiddlyTools.com/#BreadcrumbsCommand|
|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|BreadcrumbsPlugin|
|Overrides||
|Description|"crumbs" command displays current breadcrumbs list in a popup|
%/<html><hide linebreaks><a href="javascript:;" class="button" title="tiddlers viewed during this session"
onclick="var p=Popup.create(this); if (!p) return;
var d=createTiddlyElement(p,'div');
d.style.whiteSpace='normal'; d.style.width='auto'; d.style.padding='2px';
wikify('\<\<breadcrumbs [[\<html\>\<hr\>\</html\>]] [[<br>]]\>\>',d);
Popup.show(p,false); event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation();
return(false);"
>$1</a></html>
/***
|Name|BreadcrumbsPlugin|
|Author|Eric Shulman|
|Source|http://www.TiddlyTools.com/#BreadcrumbsPlugin|
|Documentation|http://www.TiddlyTools.com/#BreadcrumbsPluginInfo|
|Version|2.1.0|
|License|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler,TiddlyWiki.prototype.deleteTiddler|
|Options|##Configuration|
|Description|list/jump to tiddlers viewed during this session plus "back" button/macro|
This plugin provides a list of links to all tiddlers opened during the session, creating a "trail of breadcrumbs" from one tiddler to the next, allowing you to quickly navigate to any previously viewed tiddler, or select 'home' to reset the display to the initial set of tiddlers that were open at the start of the session (i.e., when the document was loaded into the browser).
!!!!!Documentation
<<<
see [[BreadcrumbsPluginInfo]]
<<<
!!!!!Configuration
<<<
<<option chkCreateDefaultBreadcrumbs>> automatically create breadcrumbs display (if needed)
<<option chkShowBreadcrumbs>> show/hide breadcrumbs display
<<option chkReorderBreadcrumbs>> re-order breadcrumbs when visiting a previously viewed tiddler
<<option chkBreadcrumbsHideHomeLink>> omit 'Home' link from breadcrumbs display
<<option chkBreadcrumbsSave>> prompt to save breadcrumbs when 'Home' link is pressed
<<option chkShowStartupBreadcrumbs>> show breadcrumbs for 'startup' tiddlers
<<option chkBreadcrumbsReverse>> show breadcrumbs in reverse order (most recent first)
<<option chkBreadcrumbsLimit>> limit breadcrumbs display to {{twochar{<<option txtBreadcrumbsLimit>>}}} items
<<option chkBreadcrumbsLimitOpenTiddlers>> limit open tiddlers to {{twochar{<<option txtBreadcrumbsLimitOpenTiddlers>>}}} items
<<<
!!!!!Revisions
<<<
2009.03.22 [2.1.0] added 'save breadcrumbs to tiddler' feature
| Please see [[BreadcrumbsPluginInfo]] for previous revision details |
2006.02.01 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.BreadcrumbsPlugin= {major: 2, minor: 1, revision: 0, date: new Date("March 2, 2009")};
var co=config.options; // abbreviation
// show/hide display option (default is to SHOW breadcrumbs)
if (co.chkShowBreadcrumbs===undefined) co.chkShowBreadcrumbs=true;
// REORDER breadcrumbs when visiting previously viewed tiddler (default)
if (co.chkReorderBreadcrumbs===undefined) co.chkReorderBreadcrumbs=true;
// create default breadcrumbs display as needed (default is to CREATE)
if (co.chkCreateDefaultBreadcrumbs===undefined) co.chkCreateDefaultBreadcrumbs=true;
// show breadcrumbs for 'startup' tiddlers (default is FALSE = only show crumbs for tiddlers opened after startup)
if (co.chkShowStartupBreadcrumbs===undefined) co.chkShowStartupBreadcrumbs=false;
// show crumbs in reverse order (most recent first)
if (co.chkBreadcrumbsReverse===undefined) co.chkBreadcrumbsReverse=false;
// limit number of crumbs displayed
if (co.chkBreadcrumbsLimit===undefined) co.chkBreadcrumbsLimit=false;
if (co.txtBreadcrumbsLimit===undefined) co.txtBreadcrumbsLimit=5;
// limit number of open tiddlers
if (co.chkBreadcrumbsLimitOpenTiddlers===undefined) co.chkBreadcrumbsLimitOpenTiddlers=false;
if (co.txtBreadcrumbsLimitOpenTiddlers===undefined) co.txtBreadcrumbsLimitOpenTiddlers=3;
// omit home link from breadcrumbs display
if (co.chkBreadcrumbsHideHomeLink===undefined) co.chkBreadcrumbsHideHomeLink=false;
// prompt for 'save crumbs' when 'home' button is pressed
if (co.chkBreadcrumbsSave===undefined) co.chkBreadcrumbsSave=false;
config.macros.breadcrumbs = {
crumbs: [], // the list of current breadcrumbs
askMsg: "Save current breadcrumbs before clearing?\nPress OK to save, or CANCEL to continue without saving.",
saveMsg: 'Enter the name of a tiddler in which to save the current breadcrumbs',
saveTitle: 'SavedBreadcrumbs',
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var area=createTiddlyElement(place,"span",null,"breadCrumbs",null);
area.setAttribute("homeSep",params[0]?params[0]:this.homeSeparator); // custom home separator
area.setAttribute("crumbSep",params[1]?params[1]:this.crumbSeparator); // custom crumb separator
this.render(area);
},
add: function (title) {
var thisCrumb = title;
var ind = this.crumbs.indexOf(thisCrumb);
if(ind === -1)
this.crumbs.push(thisCrumb);
else if (config.options.chkReorderBreadcrumbs)
this.crumbs.push(this.crumbs.splice(ind,1)[0]); // reorder crumbs
else
this.crumbs=this.crumbs.slice(0,ind+1); // trim crumbs
if (config.options.chkBreadcrumbsLimitOpenTiddlers)
this.limitOpenTiddlers();
this.refresh();
return false;
},
getAreas: function() {
var crumbAreas=[];
// find all DIVs with classname=="breadCrumbs"
// Note: use try/catch to avoid "Bad NPObject as private data" fatal error caused when
// some versions of embedded QuickTime player element is accessed by hasClass() function.
var all=document.getElementsByTagName("*");
for (var i=0; i<all.length; i++)
try{ if (hasClass(all[i],"breadCrumbs")) crumbAreas.push(all[i]); } catch(e) {;}
// find single DIV w/fixed ID (backward compatibility)
var byID=document.getElementById("breadCrumbs")
if (byID && !hasClass(byID,"breadCrumbs")) crumbAreas.push(byID);
if (!crumbAreas.length && config.options.chkCreateDefaultBreadcrumbs) {
// no existing crumbs display areas... create one...
var defaultArea = createTiddlyElement(null,"span",null,"breadCrumbs",null);
defaultArea.style.display= "none";
var targetArea= document.getElementById("tiddlerDisplay");
targetArea.parentNode.insertBefore(defaultArea,targetArea);
crumbAreas.push(defaultArea);
}
return crumbAreas;
},
refresh: function() {
var crumbAreas=this.getAreas();
for (var i=0; i<crumbAreas.length; i++) {
crumbAreas[i].style.display = config.options.chkShowBreadcrumbs?"block":"none";
removeChildren(crumbAreas[i]);
this.render(crumbAreas[i]);
}
},
render: function(here) {
var co=config.options; var out=""
var homeSep=here.getAttribute("homeSep"); if (!homeSep) homeSep=this.homeSeparator;
var crumbSep=here.getAttribute("crumbSep"); if (!crumbSep) crumbSep=this.crumbSeparator;
if (!co.chkBreadcrumbsHideHomeLink) {
createTiddlyButton(here,"Home",null,this.home,"tiddlyLink tiddlyLinkExisting");
out+=homeSep;
}
for (c=0; c<this.crumbs.length; c++) // remove non-existing tiddlers from crumbs
if (!store.tiddlerExists(this.crumbs[c]) && !store.isShadowTiddler(this.crumbs[c]))
this.crumbs.splice(c,1);
var count=this.crumbs.length;
if (co.chkBreadcrumbsLimit && co.txtBreadcrumbsLimit<count) count=co.txtBreadcrumbsLimit;
var list=[];
for (c=this.crumbs.length-count; c<this.crumbs.length; c++) list.push('[['+this.crumbs[c]+']]');
if (co.chkBreadcrumbsReverse) list.reverse();
out+=list.join(crumbSep);
wikify(out,here);
},
home: function() {
var cmb=config.macros.breadcrumbs;
if (config.options.chkBreadcrumbsSave && confirm(cmb.askMsg)) cmb.saveCrumbs();
story.closeAllTiddlers(); restart();
cmb.crumbs = []; var crumbAreas=cmb.getAreas();
for (var i=0; i<crumbAreas.length; i++) crumbAreas[i].style.display = "none";
return false;
},
saveCrumbs: function() {
var tid=prompt(this.saveMsg,this.saveTitle); if (!tid||!tid.length) return; // cancelled by user
var t=store.getTiddler(tid);
if(t && !confirm(config.messages.overwriteWarning.format([tid]))) return;
var who=config.options.txtUserName;
var when=new Date();
var text='[['+this.crumbs.join(']]\n[[')+']]';
var tags=t?t.tags:[]; tags.pushUnique('story');
var fields=t?t.fields:{};
store.saveTiddler(tid,tid,text,who,when,tags,fields);
story.displayTiddler(null,tid);
story.refreshTiddler(tid,null,true);
displayMessage(tid+' has been '+(t?'updated':'created'));
},
limitOpenTiddlers: function() {
var limit=config.options.txtBreadcrumbsLimitOpenTiddlers; if (limit<1) limit=1;
for (c=this.crumbs.length-1; c>=0; c--) {
var tid=this.crumbs[c];
var elem=document.getElementById(story.idPrefix+tid);
if (elem) { // tiddler is displayed
if (limit <=0) { // display limit has been reached
if (elem.getAttribute("dirty")=="true") { // tiddler is being edited
var msg="'"+tid+"' is currently being edited.\n\n";
msg+="Press OK to save and close this tiddler\nor press Cancel to leave it opened";
if (confirm(msg)) { story.saveTiddler(tid); story.closeTiddler(tid); }
}
else
story.closeTiddler(this.crumbs[c]);
}
limit--;
}
}
}
};
if (config.macros.breadcrumbs.homeSeparator==undefined) // note: not a cookie
config.macros.breadcrumbs.homeSeparator=" | ";
if (config.macros.breadcrumbs.crumbSeparator==undefined) // note: not a cookie
config.macros.breadcrumbs.crumbSeparator=" > ";
config.commands.previousTiddler = {
text: 'back',
tooltip: 'view the previous tiddler',
hideReadOnly: false,
dateFormat: 'DDD, MMM DDth YYYY hh:0mm:0ss',
handler: function(event,src,title) {
var here=story.findContainingTiddler(src); if (!here) return;
var crumbs=config.macros.breadcrumbs.crumbs;
if (crumbs.length>1) {
var crumb=crumbs[crumbs.length-2];
story.displayTiddler(here,crumb);
}
else
config.macros.breadcrumbs.home();
return false;
}
};
config.macros.previousTiddler= {
label: 'back',
prompt: 'view the previous tiddler',
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var label=params.shift(); if (!label) label=this.label;
var prompt=params.shift(); if (!prompt) prompt=this.prompt;
createTiddlyButton(place,label,prompt,function() {
var crumbs=config.macros.breadcrumbs.crumbs;
if (crumbs.length>1) {
var crumb=crumbs[crumbs.length-2];
story.displayTiddler(place,crumb);
}
else
config.macros.breadcrumbs.home();
});
}
}
// hijack story.displayTiddler() so crumbs can be refreshed when a tiddler is displayed
if (Story.prototype.breadCrumbs_coreDisplayTiddler==undefined)
Story.prototype.breadCrumbs_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,slowly)
{
var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
this.breadCrumbs_coreDisplayTiddler.apply(this,arguments);
// if not displaying tiddler during document startup, then add it to the breadcrumbs
// note: 'startingUp' flag is a global, set/reset by the core init() function
if (!startingUp || config.options.chkShowStartupBreadcrumbs) config.macros.breadcrumbs.add(title);
}
// hijack store.removeTiddler() so crumbs can be refreshed when a tiddler is deleted
if (TiddlyWiki.prototype.breadCrumbs_coreRemoveTiddler==undefined)
TiddlyWiki.prototype.breadCrumbs_coreRemoveTiddler=TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler= function(title)
{
this.breadCrumbs_coreRemoveTiddler.apply(this,arguments);
config.macros.breadcrumbs.refresh();
}
//}}}
/***
|Name|CalendarPlugin|
|Source|http://www.TiddlyTools.com/#CalendarPlugin|
|Version|2008.09.09|
|Author|Eric Shulman|
|Original Author|SteveRumsby|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|display monthly and yearly calendars|
NOTE: For enhanced date display (including popups), you must also install [[DatePlugin]]
!!!!!Usage:
<<<
|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|
|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|
|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|
|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|
|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|
|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|
|{{{<<calendar +n>>}}}<br>{{{<<calendar -n>>}}}|Produce a one-month calendar for a month +/- 'n' months from now|
<<<
!!!!!Configuration:
<<<
|''First day of week:''<br>{{{config.options.txtCalFirstDay}}}|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|
|''First day of weekend:''<br>{{{config.options.txtCalStartOfWeekend}}}|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|
<<option chkDisplayWeekNumbers>> Display week numbers //(note: Monday will be used as the start of the week)//
|''Week number display format:''<br>{{{config.options.txtWeekNumberDisplayFormat }}}|<<option txtWeekNumberDisplayFormat >>|
|''Week number link format:''<br>{{{config.options.txtWeekNumberLinkFormat }}}|<<option txtWeekNumberLinkFormat >>|
<<<
!!!!!Revisions
<<<
2008.09.10: added "+n" (and "-n") param to permit display of relative months (e.g., "+6" means "six months from now", "-3" means "three months ago". Based on suggestion from Jean.
2008.06.17: added support for config.macros.calendar.todaybg
2008.02.27: in handler(), DON'T set hard-coded default date format, so that *customized* value (pre-defined in config.macros.calendar.journalDateFmt is used.
2008.02.17: in createCalendarYear(), fix next/previous year calculation (use parseInt() to convert to numeric value). Also, use journalDateFmt for date linking when NOT using [[DatePlugin]].
2008.02.16: in createCalendarDay(), week numbers now created as TiddlyLinks, allowing quick creation/navigation to 'weekly' journals (based on request from Kashgarinn)
2008.01.08: in createCalendarMonthHeader(), "month year" heading is now created as TiddlyLink, allowing quick creation/navigation to 'month-at-a-time' journals
2007.11.30: added "return false" to onclick handlers (prevent IE from opening blank pages)
2006.08.23: added handling for weeknumbers (code supplied by Martin Budden (see "wn**" comment marks). Also, incorporated updated by Jeremy Sheeley to add caching for reminders (see [[ReminderMacros]], if installed)
2005.10.30: in config.macros.calendar.handler(), use "tbody" element for IE compatibility. Also, fix year calculation for IE's getYear() function (which returns '2005' instead of '105'). Also, in createCalendarDays(), use showDate() function (see [[DatePlugin]], if installed) to render autostyled date with linked popup. Updated calendar stylesheet definition: use .calendar class-specific selectors, add text centering and margin settings
2006.05.29: added journalDateFmt handling
<<<
***/
/***
!!!!!Code section:
***/
//{{{
version.extensions.CalendarPlugin= { major: 0, minor: 7, revision: 0, date: new Date(2008, 6, 17)};
if(config.options.txtCalFirstDay == undefined)
config.options.txtCalFirstDay = 0;
if(config.options.txtCalStartOfWeekend == undefined)
config.options.txtCalStartOfWeekend = 5;
if(config.options.chkDisplayWeekNumbers == undefined)//wn**
config.options.chkDisplayWeekNumbers = false;
if(config.options.chkDisplayWeekNumbers)
config.options.txtCalFirstDay = 0;
if(config.options.txtWeekNumberDisplayFormat == undefined)//wn**
config.options.txtWeekNumberDisplayFormat = "w0WW";
if(config.options.txtWeekNumberLinkFormat == undefined)//wn**
config.options.txtWeekNumberLinkFormat = "YYYY-w0WW";
config.macros.calendar = {};
config.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];
config.macros.calendar.todaybg = "#ccccff";
config.macros.calendar.weekendbg = "#c0c0c0";
config.macros.calendar.monthbg = "#e0e0e0";
config.macros.calendar.holidaybg = "#ffc0c0";
config.macros.calendar.journalDateFmt = "DD MMM YYYY";
config.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
config.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead
//}}}
//{{{
function calendarIsHoliday(date) // Is the given date a holiday?
{
var longHoliday = date.formatString("0DD/0MM/YYYY");
var shortHoliday = date.formatString("0DD/0MM");
for(var i = 0; i < config.macros.calendar.holidays.length; i++) {
if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday)
return true;
}
return false;
}
//}}}
//{{{
config.macros.calendar.handler = function(place,macroName,params) {
var calendar = createTiddlyElement(place, "table", null, "calendar", null);
var tbody = createTiddlyElement(calendar, "tbody", null, null, null);
var today = new Date();
var year = today.getYear();
if (year<1900) year+=1900;
// get format for journal link by reading from SideBarOptions (ELS 5/29/06 - based on suggestion by Martin Budden)
var text = store.getTiddlerText("SideBarOptions");
var re = new RegExp("<<(?:newJournal)([^>]*)>>","mg"); var fm = re.exec(text);
if (fm && fm[1]!=null) { var pa=fm[1].readMacroParams(); if (pa[0]) this.journalDateFmt = pa[0]; }
var month=-1;
if (params[0] == "thismonth") {
var month=today.getMonth();
} else if (params[0] == "lastmonth") {
var month = today.getMonth()-1; if (month==-1) { month=11; year--; }
} else if (params[0] == "nextmonth") {
var month = today.getMonth()+1; if (month>11) { month=0; year++; }
} else if (params[0]&&"+-".indexOf(params[0].substr(0,1))!=-1) {
var month = today.getMonth()+parseInt(params[0]);
if (month>11) { year+=Math.floor(month/12); month%=12; };
if (month<0) { year+=Math.floor(month/12); month=12+month%12; }
} else if (params[0]) {
year = params[0];
if(params[1]) month=parseInt(params[1])-1;
if (month>11) month=11; if (month<0) month=0;
}
if (month!=-1) {
cacheReminders(new Date(year, month, 1, 0, 0), 31);
createCalendarOneMonth(tbody, year, month);
} else {
cacheReminders(new Date(year, 0, 1, 0, 0), 366);
createCalendarYear(tbody, year);
}
window.reminderCacheForCalendar = null;
}
//}}}
//{{{
//This global variable is used to store reminders that have been cached
//while the calendar is being rendered. It will be renulled after the calendar is fully rendered.
window.reminderCacheForCalendar = null;
//}}}
//{{{
function cacheReminders(date, leadtime)
{
if (window.findTiddlersWithReminders == null) return;
window.reminderCacheForCalendar = {};
var leadtimeHash = [];
leadtimeHash [0] = 0;
leadtimeHash [1] = leadtime;
var t = findTiddlersWithReminders(date, leadtimeHash, null, 1);
for(var i = 0; i < t.length; i++) {
//just tag it in the cache, so that when we're drawing days, we can bold this one.
window.reminderCacheForCalendar[t[i]["matchedDate"]] = "reminder:" + t[i]["params"]["title"];
}
}
//}}}
//{{{
function createCalendarOneMonth(calendar, year, mon)
{
var row = createTiddlyElement(calendar, "tr", null, null, null);
createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);
row = createTiddlyElement(calendar, "tr", null, null, null);
createCalendarDayHeader(row, 1);
createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarMonth(calendar, year, mon)
{
var row = createTiddlyElement(calendar, "tr", null, null, null);
createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);
row = createTiddlyElement(calendar, "tr", null, null, null);
createCalendarDayHeader(row, 1);
createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarYear(calendar, year)
{
var row;
row = createTiddlyElement(calendar, "tr", null, null, null);
var back = createTiddlyElement(row, "td", null, null, null);
var backHandler = function() {
removeChildren(calendar);
createCalendarYear(calendar, parseInt(year)-1);
return false; // consume click
};
createTiddlyButton(back, "<", "Previous year", backHandler);
back.align = "center";
var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);
yearHeader.align = "center";
yearHeader.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?22:19);//wn**
var fwd = createTiddlyElement(row, "td", null, null, null);
var fwdHandler = function() {
removeChildren(calendar);
createCalendarYear(calendar, parseInt(year)+1);
return false; // consume click
};
createTiddlyButton(fwd, ">", "Next year", fwdHandler);
fwd.align = "center";
createCalendarMonthRow(calendar, year, 0);
createCalendarMonthRow(calendar, year, 3);
createCalendarMonthRow(calendar, year, 6);
createCalendarMonthRow(calendar, year, 9);
}
//}}}
//{{{
function createCalendarMonthRow(cal, year, mon)
{
var row = createTiddlyElement(cal, "tr", null, null, null);
createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);
createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);
createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);
row = createTiddlyElement(cal, "tr", null, null, null);
createCalendarDayHeader(row, 3);
createCalendarDayRows(cal, year, mon);
}
//}}}
//{{{
function createCalendarMonthHeader(cal, row, name, nav, year, mon)
{
var month;
if (nav) {
var back = createTiddlyElement(row, "td", null, null, null);
back.align = "center";
back.style.background = config.macros.calendar.monthbg;
var backMonHandler = function() {
var newyear = year;
var newmon = mon-1;
if(newmon == -1) { newmon = 11; newyear = newyear-1;}
removeChildren(cal);
cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
createCalendarOneMonth(cal, newyear, newmon);
return false; // consume click
};
createTiddlyButton(back, "<", "Previous month", backMonHandler);
month = createTiddlyElement(row, "td", null, "calendarMonthname")
createTiddlyLink(month,name,true);
month.setAttribute("colSpan", config.options.chkDisplayWeekNumbers?6:5);//wn**
var fwd = createTiddlyElement(row, "td", null, null, null);
fwd.align = "center";
fwd.style.background = config.macros.calendar.monthbg;
var fwdMonHandler = function() {
var newyear = year;
var newmon = mon+1;
if(newmon == 12) { newmon = 0; newyear = newyear+1;}
removeChildren(cal);
cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
createCalendarOneMonth(cal, newyear, newmon);
return false; // consume click
};
createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);
} else {
month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
month.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?8:7);//wn**
}
month.align = "center";
month.style.background = config.macros.calendar.monthbg;
}
//}}}
//{{{
function createCalendarDayHeader(row, num)
{
var cell;
for(var i = 0; i < num; i++) {
if (config.options.chkDisplayWeekNumbers) createTiddlyElement(row, "td");//wn**
for(var j = 0; j < 7; j++) {
var d = j + (config.options.txtCalFirstDay - 0);
if(d > 6) d = d - 7;
cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);
if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))
cell.style.background = config.macros.calendar.weekendbg;
}
}
}
//}}}
//{{{
function createCalendarDays(row, col, first, max, year, mon) {
var i;
if (config.options.chkDisplayWeekNumbers){
if (first<=max) {
var ww = new Date(year,mon,first);
var td=createTiddlyElement(row, "td");//wn**
var link=createTiddlyLink(td,ww.formatString(config.options.txtWeekNumberLinkFormat),false);
link.appendChild(document.createTextNode(ww.formatString(config.options.txtWeekNumberDisplayFormat)));
}
else createTiddlyElement(row, "td", null, null, null);//wn**
}
for(i = 0; i < col; i++)
createTiddlyElement(row, "td", null, null, null);
var day = first;
for(i = col; i < 7; i++) {
var d = i + (config.options.txtCalFirstDay - 0);
if(d > 6) d = d - 7;
var daycell = createTiddlyElement(row, "td", null, null, null);
var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);
if(day > 0 && day <= max) {
var celldate = new Date(year, mon, day);
// ELS 2005.10.30: use <<date>> macro's showDate() function to create popup
// ELS 5/29/06 - use journalDateFmt
if (window.showDate)
showDate(daycell,celldate,"popup","DD",config.macros.calendar.journalDateFmt,true, isaWeekend);
else {
if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;
var title = celldate.formatString(config.macros.calendar.journalDateFmt);
if(calendarIsHoliday(celldate))
daycell.style.background = config.macros.calendar.holidaybg;
var now=new Date();
if ((now-celldate>=0) && (now-celldate<86400000)) // is today?
daycell.style.background = config.macros.calendar.todaybg;
if(window.findTiddlersWithReminders == null) {
var link = createTiddlyLink(daycell, title, false);
link.appendChild(document.createTextNode(day));
} else
var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);
}
}
day++;
}
}
//}}}
//{{{
// We've clicked on a day in a calendar - create a suitable pop-up of options.
// The pop-up should contain:
// * a link to create a new entry for that date
// * a link to create a new reminder for that date
// * an <hr>
// * the list of reminders for that date
// NOTE: The following code is only used when [[DatePlugin]] is not present
function onClickCalendarDate(e)
{
var button = this;
var date = button.getAttribute("title");
var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));
date = dat.formatString(config.macros.calendar.journalDateFmt);
var popup = createTiddlerPopup(this);
popup.appendChild(document.createTextNode(date));
var newReminder = function() {
var t = store.getTiddlers(date);
displayTiddler(null, date, 2, null, null, false, false);
if(t) {
document.getElementById("editorBody" + date).value += "\n<<reminder day:" + dat.getDate() +
" month:" + (dat.getMonth()+1) + " year:" + (dat.getYear()+1900) + " title: >>";
} else {
document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +
" month:" + (dat.getMonth()+1) +" year:" + (dat.getYear()+1900) + " title: >>";
}
return false; // consume click
};
var link = createTiddlyButton(popup, "New reminder", null, newReminder);
popup.appendChild(document.createElement("hr"));
var t = findTiddlersWithReminders(dat, [0,14], null, 1);
for(var i = 0; i < t.length; i++) {
link = createTiddlyLink(popup, t[i].tiddler, false);
link.appendChild(document.createTextNode(t[i].tiddler));
}
return false; // consume click
}
//}}}
//{{{
function calendarMaxDays(year, mon)
{
var max = config.macros.calendar.monthdays[mon];
if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) max++;
return max;
}
//}}}
//{{{
function createCalendarDayRows(cal, year, mon)
{
var row = createTiddlyElement(cal, "tr", null, null, null);
var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
if(first1 < 0) first1 = first1 + 7;
var day1 = -first1 + 1;
var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
if(first2 < 0) first2 = first2 + 7;
var day2 = -first2 + 1;
var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
if(first3 < 0) first3 = first3 + 7;
var day3 = -first3 + 1;
var max1 = calendarMaxDays(year, mon);
var max2 = calendarMaxDays(year, mon+1);
var max3 = calendarMaxDays(year, mon+2);
while(day1 <= max1 || day2 <= max2 || day3 <= max3) {
row = createTiddlyElement(cal, "tr", null, null, null);
createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;
createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;
}
}
//}}}
//{{{
function createCalendarDayRowsSingle(cal, year, mon)
{
var row = createTiddlyElement(cal, "tr", null, null, null);
var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
if(first1 < 0) first1 = first1+ 7;
var day1 = -first1 + 1;
var max1 = calendarMaxDays(year, mon);
while(day1 <= max1) {
row = createTiddlyElement(cal, "tr", null, null, null);
createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
}
}
//}}}
//{{{
setStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { text-align:center; } .calendar, .calendar a { margin:0px !important; padding:0px !important; }", "calendarStyles");
//}}}
// // override cookie settings for CalendarPlugin:
//{{{
config.options.txtCalFirstDay=6;
config.options.txtCalStartOfWeekend=5;
//}}}
// // override internal default settings for CalendarPlugin:
//{{{
config.macros.calendar.journalDateFmt="DDD MMM 0DD YYYY";
//}}}
/***
|Name|ClickifyPlugin|
|Source|http://www.TiddlyTools.com/#ClickifyPlugin|
|Documentation|http://www.TiddlyTools.com/#ClickifyPlugin|
|Version|1.0.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|re-compute parameters when a 'command link' macro is clicked|
!!!!!Usage
<<<
Normally, when you use a //computed parameter// in a macro, it's value is determined when the macro is rendered. The {{{<<clickify>>}}} macro can be used to force the macro parameters of an 'on-click' command link (such as created by the {{{<<newTiddler>>}}} macro) to be automatically re-computed when the command link is clicked, rather than when it is initially displayed. This allows use of computed values that depend upon data that may change between the time the macro is rendered and when it's action is actually triggered by a click.
To apply this extended processing to any macro that creates a command link, simply insert the 'clickify' keyword in front of the usual macro name, like this:
{{{
<<clickify macroName param param param ...>>
}}}
<<<
!!!!!Example
<<<
When {{{<<newTiddler>>}}} is clicked, prompt for a title and set default text to current timestamp:
{{{
<<clickify newTiddler title:{{prompt('enter a title','NewTiddler')}} text:{{new Date()}}>>
}}}
><<clickify newTiddler title:{{prompt('enter a title','NewTiddler')}} text:{{new Date()}}>>
<<<
!!!!!Revisions
<<<
2009.02.08 [1.0.1] make sure command link has been rendered before trying to modify it
2009.01.25 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ClickifyPlugin={major: 1, minor: 0, revision: 1, date: new Date(2009,2,8)};
config.macros.clickify={
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var cmd='<<'+paramString+'>>';
var e=createTiddlyElement(place,'span');
wikify(cmd.replace(/alert\(|prompt\(|confirm\(/g,'isNaN('),e);
var b=e.getElementsByTagName('a')[0]; if (!b) return;
b.setAttribute('cmd',cmd);
b.onclick=function(ev) {
var cmd=this.getAttribute('cmd');
var e=createTiddlyElement(this.parentNode,'span');
e.style.display='none';
wikify(cmd,e);
e.getElementsByTagName('a')[0].onclick();
this.parentNode.removeChild(e);
}
}
}
//}}}
/***
|Name|CollapseTiddlersPlugin|
|Source|http://gensoft.revhost.net/Collapse.html|
|Version|2008.10.05|
|Author|Bradley Meck (modified by ELS)|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|CollapsedTemplate|
|Overrides||
|Description|show/hide content of a tiddler while leaving tiddler title visible|
|ELS 10/5/2008: collapseAll() and expandAll(): added "return false" to button handlers to prevent IE page transition |
|ELS 3/6/2008: refactored code for size reduction, readability, and I18N/L10N-readiness. Also added 'folded' flag to tiddler elements (for use by other plugins that need to know if tiddler is folded (e.g., [[SinglePageModePlugin]]) |
|ELS 10/11/2007: moved [[FoldFirst]] inline script and converted to {{{<<foldFirst>>}}} macro. |
|ELS 9/12/2007: suspend/resume SinglePageMode (SPM/TPM/BPM) when folding/unfolding tiddlers |
|ELS 6/5/2007: add "return false" at the end of each command handler to prevent IE 'page transition' problem. |
|ELS 3/30/2007: add a shadow definition for CollapsedTemplate. Tweak ViewTemplate shadow so "fold/unfold" and "focus" toolbar items automatically appear when using default templates. Remove error check for "CollapsedTemplate" existence, since shadow version will now always work as a fallback. |
|ELS 2/24/2006: added fallback to "CollapsedTemplate" if "WebCollapsedTemplate" is not found |
|ELS 2/6/2006: added check for 'readOnly' flag to use alternative "WebCollapsedTemplate" |
***/
//{{{
config.shadowTiddlers.CollapsedTemplate=
"<!--{{{-->\
<div class='toolbar' macro='toolbar expandTiddler collapseOthers closeTiddler closeOthers +editTiddler permalink references jump'></div>\
<div class='title' macro='view title'></div>\
<!--}}}-->";
// automatically tweak shadow ViewTemplate to add "collapseTiddler collapseOthers" commands
config.shadowTiddlers.ViewTemplate=config.shadowTiddlers.ViewTemplate.replace(/closeTiddler/,"collapseTiddler collapseOthers closeTiddler");
config.commands.collapseTiddler = {
text: "fold",
tooltip: "Collapse this tiddler",
collapsedTemplate: "CollapsedTemplate",
webCollapsedTemplate: "WebCollapsedTemplate",
handler: function(event,src,title) {
var e = story.findContainingTiddler(src); if (!e) return false;
// don't fold tiddlers that are being edited!
if(story.isDirty(e.getAttribute("tiddler"))) return false;
var t=config.commands.collapseTiddler.getCollapsedTemplate();
config.commands.collapseTiddler.saveTemplate(e);
config.commands.collapseTiddler.display(title,t);
e.setAttribute("folded","true");
return false;
},
getCollapsedTemplate: function() {
if (readOnly&&store.tiddlerExists(this.webCollapsedTemplate))
return this.webCollapsedTemplate;
else
return this.collapsedTemplate
},
saveTemplate: function(e) {
if (e.getAttribute("savedTemplate")==undefined)
e.setAttribute("savedTemplate",e.getAttribute("template"));
},
// fold/unfold tiddler with suspend/resume of single/top/bottom-of-page mode
display: function(title,t) {
var opt=config.options;
var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
story.displayTiddler(null,title,t);
opt.chkBottomOfPageMode=saveBPM;
opt.chkTopOfPageMode=saveTPM;
opt.chkSinglePageMode=saveSPM;
}
}
config.commands.expandTiddler = {
text: "unfold",
tooltip: "Expand this tiddler",
handler: function(event,src,title) {
var e = story.findContainingTiddler(src); if (!e) return false;
var t = e.getAttribute("savedTemplate");
config.commands.collapseTiddler.display(title,t);
e.setAttribute("folded","false");
return false;
}
}
config.macros.collapseAll = {
text: "collapse all",
tooltip: "Collapse all tiddlers",
handler: function(place,macroName,params,wikifier,paramString,tiddler){
createTiddlyButton(place,this.text,this.tooltip,function(){
story.forEachTiddler(function(title,tiddler){
if(story.isDirty(title)) return;
var t=config.commands.collapseTiddler.getCollapsedTemplate();
config.commands.collapseTiddler.saveTemplate(tiddler);
config.commands.collapseTiddler.display(title,t);
tiddler.folded=true;
});
return false;
})
}
}
config.macros.expandAll = {
text: "expand all",
tooltip: "Expand all tiddlers",
handler: function(place,macroName,params,wikifier,paramString,tiddler){
createTiddlyButton(place,this.text,this.tooltip,function(){
story.forEachTiddler(function(title,tiddler){
var t=config.commands.collapseTiddler.getCollapsedTemplate();
if(tiddler.getAttribute("template")!=t) return; // re-display only if collapsed
var t=tiddler.getAttribute("savedTemplate");
config.commands.collapseTiddler.display(title,t);
tiddler.folded=false;
});
return false;
})
}
}
config.commands.collapseOthers = {
text: "focus",
tooltip: "Expand this tiddler and collapse all others",
handler: function(event,src,title) {
var e = story.findContainingTiddler(src); if (!e) return false;
story.forEachTiddler(function(title,tiddler) {
if(story.isDirty(title)) return;
var t=config.commands.collapseTiddler.getCollapsedTemplate();
if (e==tiddler) t=e.getAttribute("savedTemplate");
config.commands.collapseTiddler.saveTemplate(tiddler);
config.commands.collapseTiddler.display(title,t);
tiddler.folded=(e!=tiddler);
})
return false;
}
}
// {{{<<foldFirst>>}}} macro forces tiddler to be folded when *initially* displayed.
// Subsequent re-render does NOT re-fold tiddler, but closing/re-opening tiddler DOES cause it to fold first again.
config.macros.foldFirst = {
handler: function(place,macroName,params,wikifier,paramString,tiddler){
var e=story.findContainingTiddler(place);
if (e.getAttribute("foldedFirst")=="true") return; // already been folded once
var title=e.getAttribute("tiddler")
var t=config.commands.collapseTiddler.getCollapsedTemplate();
config.commands.collapseTiddler.saveTemplate(e);
config.commands.collapseTiddler.display(title,t);
e.setAttribute("folded","true");
e.setAttribute("foldedFirst","true"); // only when tiddler is first rendered
return false;
}
}
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::CollapsedToolbar]]'></div>
<div class='title' macro='view title'></div>
<!--}}}-->
/***
|Name|CommentPlugin|
|Source|http://www.TiddlyTools.com/#CommentPlugin|
|Documentation|http://www.TiddlyTools.com/#CommentPluginInfo|
|Version|2.9.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||
|Description|automatically insert formatted comments into tiddler content|
!!!!!Documentation
>see [[CommentPluginInfo]]
!!!!!Configuration
>see [[CommentPluginInfo]]
!!!!!Revisions
<<<
2009.03.09 [2.9.2] added marker:... macro parameter
| please see [[CommentPluginInfo]] for previous revision details |
2006.04.20 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.CommentPlugin= {major: 2, minor: 9, revision: 2, date: new Date(2009,3,9)};
config.macros.comment= {
marker: '/%'+'comment'+'%/',
fmt: "__''%subject%''__\n^^posted by %who% on %when%^^\n<<<\n%message%\n<<<\n",
datefmt: 'DDD, MMM DDth, YYYY at hh12:0mm:0ss am',
tags: '',
reverse: false,
handler: function(place,macroName,params,wikifier,paramstring,tiddler) {
var span=createTiddlyElement(place,'span');
var here=story.findContainingTiddler(place);
if (here) var tid=here.getAttribute('tiddler'); // containing tiddler title
span.setAttribute('here',tid);
var target=(params[0]&¶ms[0].length&¶ms[0]!='here')?params[0]:tid; // target title
span.setAttribute('target',target);
var overwrite=(params[1]&¶ms[1].toLowerCase()=='overwrite'); if (overwrite) params.shift();
span.setAttribute('overwrite',overwrite?'true':'false');
var reverse=(params[1]&¶ms[1].toLowerCase()=='reverse'); if (reverse) params.shift();
span.setAttribute('reverse',(reverse||this.reverse)?'true':'false');
var marker=this.marker;
if (params[1]&¶ms[1].substr(0,7)=='marker:') {
var marker='/%'+params[1].substr(7)+'%/';
params.shift();
}
span.setAttribute('marker',marker);
var tags=(params[1]&¶ms[1].length)?params[1]:this.tags; // target tags
span.setAttribute('tags',tags);
var fmt=(params[2]&¶ms[2].length)?params[2]:this.fmt; // output format
span.setAttribute('fmt',fmt.unescapeLineBreaks());
var datefmt=(params[3]&¶ms[3].length)?params[3]:this.datefmt; // date format
span.setAttribute('datefmt',datefmt.unescapeLineBreaks());
var html=this.html;
html=html.replace(/%nosubject%/g,(fmt.indexOf('%subject%')==-1)?'none':'block');
html=html.replace(/%nomessage%/g,(fmt.indexOf('%message%')==-1)?'none':'block');
var subjtxt=''; var msgtxt='';
html=html.replace(/%subjtxt%/g,subjtxt);
html=html.replace(/%msgtxt%/g,msgtxt);
span.innerHTML=html;
},
html: "<form style='display:inline;margin:0;padding:0;'>\
<div style='display:%nosubject%'>\
subject:<br>\
<input type='text' name='subject' title='enter subject text' style='width:100%' value='%subjtxt%'>\
</div>\
<div style='display:%nomessage%'>\
message:<br>\
<textarea name='message' rows='7' title='enter message text' \
style='width:100%'>%msgtxt%</textarea>\
</div>\
<center>\
<i>Please enter your information and then press</i>\
<input type='button' value='post' onclick='\
var s=this.form.subject; var m=this.form.message;\
if (\"%nosubject%\"!=\"none\" && !s.value.length)\
{ alert(\"Please enter a subject\"); s.focus(); return false; }\
if (\"%nomessage%\"!=\"none\" && !m.value.length)\
{ alert(\"Please enter a message\"); m.focus(); return false; }\
var here=this.form.parentNode.getAttribute(\"here\");\
var reverse=this.form.parentNode.getAttribute(\"reverse\")==\"true\";\
var target=this.form.parentNode.getAttribute(\"target\");\
var marker=this.form.parentNode.getAttribute(\"marker\");\
var tags=this.form.parentNode.getAttribute(\"tags\").readBracketedList();\
var fmt=this.form.parentNode.getAttribute(\"fmt\");\
var datefmt=this.form.parentNode.getAttribute(\"datefmt\");\
var overwrite=this.form.parentNode.getAttribute(\"overwrite\")==\"true\";\
config.macros.comment.addComment(here,reverse,target,tags,fmt,datefmt,\
s.value,m.value,overwrite,marker);'>\
</center>\
</form>",
addComment: function(here,reverse,target,newtags,fmt,datefmt,subject,message,overwrite,marker) {
var UTC=new Date().convertToYYYYMMDDHHMMSSMMM();
var rand=Math.random().toString();
var who=config.options.txtUserName;
var when=new Date().formatString(datefmt);
target=target.replace(/%tiddler%/g,here);
target=target.replace(/%UTC%/g,UTC);
target=target.replace(/%random%/g,rand);
target=target.replace(/%who%/g,who);
target=target.replace(/%when%/g,when);
target=target.replace(/%subject%/g,subject);
var t=store.getTiddler(target);
var text=t?t.text:'';
var modifier=t?t.modifier:config.options.txtUserName;
var modified=t?t.modified:new Date();
var tags=t?t.tags:[];
for(var i=0; i<newtags.length; i++) tags.pushUnique(newtags[i]);
var fields=t?t.fields:{};
var out=fmt;
out=out.replace(/%tiddler%/g,here);
out=out.replace(/%UTC%/g,UTC);
out=out.replace(/%when%/g,when);
out=out.replace(/%who%/g,who);
out=out.replace(/%subject%/g,subject);
out=out.replace(/%message%/g,message);
var pos=text.indexOf(marker);
if (pos==-1) pos=text.length; // no marker - insert at end
else if (reverse) pos+=marker.length; // reverse order by inserting AFTER marker
var newtxt=overwrite?out:(text.substr(0,pos)+out+text.substr(pos));
store.saveTiddler(target,target,newtxt,modifier,modified,tags,fields);
if (document.getElementById(story.idPrefix+target))
story.refreshTiddler(target,DEFAULT_VIEW_TEMPLATE,true);
if (here!=target && document.getElementById(story.idPrefix+here))
story.refreshTiddler(here,DEFAULT_VIEW_TEMPLATE,true);
}
};
//}}}
Please use the contact form on my main site:
>http://www.TiddlyTools.com#Contact
/***
|Name|CookieManagerPlugin|
|Source|http://www.TiddlyTools.com/#CookieManagerPlugin|
|Version|2.3.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||
|Options|##Configuration|
|Description|view/add/delete browser-based cookies and "bake" cookies to CookieJar tiddler for 'sticky' settings|
!!!!!Usage
<<<
This plugin provides an interactive control panel that lets you select, view, modify, or delete any of the current values for TiddlyWiki options that have been stored as local, private, //browser cookies//. You can also use the control panel to "bake cookies", which generates a set of javascript statements that assign hard-coded option values to the TiddlyWiki internal variables that correspond to the current browser cookie settings. These hard-coded values are then stored in the [[CookieJar]] tiddler, which is tagged with<<tag systemConfig>> so that each time the document is loaded, the baked cookie settings will be automatically applied.
When a set of baked cookies is added to the [[CookieJar]], it is automatically surrounded by a conditional test so that the hard-coded settings will only be applied for the username that was in effect when they were initially generated. In this way, if you publish or share your document with others, //your// particular baked cookie settings are not automatically applied to others, so that their own browser-based cookie settings (if defined) will be applied as usual.
Whenever you "bake cookies", new hard-coded javascript assignment statements are *appended* to the end of the [[CookieJar]]. However, any baked cookies that were previously generated and stored in the [[CookieJar]] are not automatically removed from the tiddler. As a result, because the most recently baked cookie settings in the [[CookieJar]] are always the last to be processed, the values assigned by older baked cookies are immediately overridden by the values from the newest baked cookies, so that the newest values will be in effect when the CookieJar startup processing is completed.
Each time you bake a new batch of cookies, it is recommended that you should review and hand-edit the [[CookieJar]] to remove any "stale cookies" or merge the old and new sets of baked cookies into a single block to simplify readability (as well as saving a little tiddler storage space). Of course, you can also hand-edit the [[CookieJar]] tiddler at any time simply to remove a few individual //baked cookies// if they are no longer needed, and you can even delete the entire [[CookieJar]] tiddler and start fresh, if that is appropriate. Please note that changing or deleting a baked cookie does not alter the current value of the corresponding option setting, and any changes you make to the [[CookieJar]] will only be applied after you have saved and reloaded the document in your browser.
<<<
!!!!!Examples
<<<
{{{<<cookieManager>>}}}
{{smallform small center{
@@display:block;width:35em;<<cookieManager>>@@}}}
<<<
!!!!!Configuration
<<<
<<option chkAllowBrowserCookies>> store ~TiddlyWiki option settings using private browser cookies
<<option chkMonitorBrowserCookies>> monitor browser cookie activity (show a message whenever a cookie is set or deleted)
<<option chkCookieManagerAddToAdvancedOptions>> display [[CookieManager]] in [[AdvancedOptions]]
//note: this setting does not take effect until you reload the document//
<<<
!!!!!Revisions
<<<
2008.09.14 [2.3.2] fixed handling for blocked cookies (was still allowing some blocked cookies to be set)
2008.09.12 [2.3.1] added blocked[] array and allowBrowserCookie() test function for selective blocking of changes to browser cookies based on cookie name
2008.09.08 [2.3.0] extensive code cleanup: defined removeCookie(), renamed cookies, added 'button' param for stand-alone "bake cookies" button, improved init of shadow [[CookieManager]] and [[CookieJar]] tiddlers for compatibility with new [[CookieSaverPlugin]].
2008.07.11 [2.2.1] fixed recursion error in hijack for saveOptionCookie()
2008.06.26 [2.2.0] added chkCookieManagerNoNewCookies option
2008.06.05 [2.1.3] replaced hard-coded definition for "CookieJar" title with option variable
2008.05.12 [2.1.2] add "cookies" task to backstage (moved from BackstageTasks)
2008.04.09 [2.1.0] added options: chkCookieManagerAddToAdvancedOptions
2008.04.08 [2.0.1] automatically include CookieManager control panel in AdvancedOptions shadow tiddler
2007.08.02 [2.0.0] converted from inline script
2007.04.29 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.CookieManagerPlugin= {major: 2, minor: 3, revision: 1, date: new Date(2008,9,12)};
//}}}
//{{{
config.macros.cookieManager = {
target:
config.options.txtCookieJar||"CookieJar",
blockedCookies:
[],
allowBrowserCookie: function(name) {
return true;
},
displayStatus: function(msg) {
if (config.options.chkMonitorBrowserCookies && !startingUp)
displayMessage("CookieManager: "+msg);
},
init: function() {
if (config.options.txtCookieJar===undefined)
config.options.txtCookieJar=this.target;
if (config.options.chkAllowBrowserCookies===undefined)
config.options.chkAllowBrowserCookies=true;
if (config.options.chkMonitorBrowserCookies===undefined)
config.options.chkMonitorBrowserCookies=false;
config.shadowTiddlers.CookieManager=
"/***\n"
+"!!![[Browser cookies:|CookieManagerPlugin]] "
+"{{fine{<<option chkAllowBrowserCookies>>enable <<option chkMonitorBrowserCookies>>monitor}}}\n"
+"^^Review, modify, or delete browser cookies..."
+"To block specific cookies, see [[CookieManagerPluginConfig]].^^\n"
+"@@display:block;width:30em;{{smallform small{\n<<cookieManager>>}}}@@\n"
+"***/\n";
// add CookieManager to shadow CookieJar
var h="/***\n<<tiddler CookieManager>>\n***/\n";
var t=(config.shadowTiddlers[this.target]||"").replace(new RegExp(h.replace(/\*/g,'\\*'),''),'')
config.shadowTiddlers[this.target]=h+t;
if (config.options.chkCookieManagerAddToAdvancedOptions===undefined)
config.options.chkCookieManagerAddToAdvancedOptions=true;
if (config.options.chkCookieManagerAddToAdvancedOptions)
config.shadowTiddlers.AdvancedOptions+="\n!!CookieManager\n><<tiddler CookieManager>>";
// add "cookies" backstage task
if (config.tasks && !config.tasks.cookies) { // for TW2.2b3 or above
config.tasks.cookies = {
text: "cookies",
tooltip: "manage cookie-based option settings",
content: "{{groupbox{<<tiddler CookieManager>><<tiddler [["+this.target+"]]>>}}}"
}
config.backstageTasks.push("cookies");
}
},
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var span=createTiddlyElement(place,"span");
span.innerHTML=(params[0]&¶ms[0].toLowerCase()=="button")?this.button:this.panel;
this.setList(span.firstChild.list);
},
panel: '<form style="display:inline;margin:0;padding:0" onsubmit="return false"><!--\
--><select style="width:99%" name="list" \
onchange="this.form.val.value=this.value.length?config.options[this.value]:\'\';"><!--\
--></select><br>\
<input type="text" style="width:98%;margin:0;" name="val" title="enter an option value"><br>\
<input type="button" style="width:33%;margin:0;" value="get" title="refresh list" \
onclick="config.macros.cookieManager.setList(this.form.list);"><!--\
--><input type="button" style="width:33%;margin:0;" value="set" title="save cookie value" \
onclick="var cmc=config.macros.cookieManager;\
var opt=this.form.list.value; var v=this.form.val.value; \
var msg=opt+\' is a blocked cookie. OK to proceed?\';\
if ((!cmc.blockedCookies.contains(opt) && cmc.allowBrowserCookie(opt))||confirm(msg)) {\
config.options[opt]=opt.substr(0,3)==\'txt\'?v:(v.toLowerCase()==\'true\'); \
saveOptionCookie(opt);config.macros.cookieManager.setList(this.form.list);\
}"><!--\
--><input type="button" style="width:33%;margin:0;" value="del" title="remove cookie" \
onclick="var cmc=config.macros.cookieManager; var opt=this.form.list.value; \
var msg=opt+\' is a blocked cookie. OK to proceed?\';\
if ((!cmc.blockedCookies.contains(opt) && cmc.allowBrowserCookie(opt))||confirm(msg)) {\
removeCookie(this.form.list.value,true); \
cmc.setList(this.form.list);\
}"><br>\
<input type="button" style="width:50%;margin:0;" value="bake cookies" \
title="save current cookie-based option values into a tiddler" \
onclick="return config.macros.cookieManager.bake(this,false)"><!--\
--><input type="button" style="width:50%;margin:0;" value="bake all options" \
title="save ALL option values (including NON-COOKIE values) into a tiddler" \
onclick="return config.macros.cookieManager.bake(this,true)"><!--\
--></form>\
',
button: '<form style="display:inline;margin:0;padding:0" onsubmit="return false"><!--\
--><input type="button" style="margin:0;" value="bake cookies" \
title="save current browser-based cookie values into a tiddler" \
onclick="return config.macros.cookieManager.bake(this,false)"><!--\
--></form>\
',
getCookieList: function() {
var cookies = { };
if (document.cookie != "") {
var p = document.cookie.split("; ");
for (var i=0; i < p.length; i++) {
var pos=p[i].indexOf("=");
if (pos==-1) cookies[p[i]]="";
else cookies[p[i].substr(0,pos)]=unescape(p[i].slice(pos+1));
}
}
var opt=new Array(); for (var i in config.options) if (cookies[i]) opt.push(i); opt.sort();
return opt;
},
setList: function(list) {
if (!list) return false;
var opt=this.getCookieList();
var sel=list.selectedIndex;
while (list.options.length > 1) { list.options[1]=null; } // clear list (except for header item)
list.options[0]=new Option("There are "+opt.length+" cookies...","",false,false);
if (!opt.length) { list.form.val.value=""; return; } // no cookies
var c=1;
for(var i=0; i<opt.length; i++) {
var txt="";
if (opt[i].substr(0,3)=="chk")
txt+="["+(config.options[opt[i]]?"\u221A":"_")+"] ";
txt+=opt[i];
list.options[c++]=new Option(txt,opt[i],false,false);
}
list.selectedIndex=sel>0?sel:0;
list.form.val.value=sel>0?config.options[list.options[sel].value]:"";
},
header:
"/***\n"
+"!!![[Baked cookies:|CookieManagerPlugin]]\n"
+"^^Press {{smallform{<<cookieManager button>>}}} to save the current browser cookies... "
+"then hand-edit this section to customize the results.^^\n"
+"***/\n",
format: function(name) {
if (name.substr(0,3)=='chk')
return '\tconfig.options.'+name+'='+(config.options[name]?'true;':'false;');
return '\tconfig.options.'+name+'="'+config.options[name]+'";';
},
bake: function(here,all) {
if (story.isDirty(this.target)) return false; // target is being hand-edited... do nothing
var text=store.getTiddlerText(this.target);
if (text.indexOf(this.header)==-1) {
text+=this.header;
displayMessage("CookieManager: added 'Baked Cookies' section to CookieJar");
}
var who=config.options.txtUserName;
var when=new Date();
var tags=['systemConfig'];
var tid=store.getTiddler(this.target)||store.saveTiddler(this.target,this.target,text,who,when,tags,{});
if (!tid) return false; // if no target... do nothing
if (all) {
var opts=new Array();
for (var i in config.options) if (i.substr(0,3)=='chk'||i.substr(0,3)=='txt') opts.push(i);
opts.sort();
}
else var opts=this.getCookieList();
var t=tid.text;
if (t.indexOf(this.header)==-1) t+=this.header;
t+='\n// '+opts.length+(all?' options':' cookies')+' saved ';
t+=when.formatString('on DDD, MMM DDth YYYY at 0hh:0mm:0ss');
t+=' by '+who+'//\n';
t+='//^^(edit/remove username check and/or individual option settings as desired)^^//\n';
t+='//{{{\n';
t+='if (config.options.txtUserName=="'+who+'") {\n';
for (i=0; i<opts.length; i++) t+=config.macros.cookieManager.format(opts[i])+"\n";
t+='}\n//}}}\n';
store.saveTiddler(this.target,this.target,t,who,when,tags,tid?tid.fields:{});
story.displayTiddler(story.findContainingTiddler(this),this.target);
story.refreshTiddler(this.target,null,true);
var msg=opts.length+(all?' options':' cookies')+' have been saved in '+this.target+'. ';
msg+='Please review all stored settings.';
displayMessage(msg);
return false;
}
}
//}}}
//{{{
// Hijack saveOptionCookie() to add cookie blocking and monitoring messages
config.macros.cookieManager.saveOptionCookie=saveOptionCookie;
window.saveOptionCookie=function(name,force)
{
var cmc=config.macros.cookieManager; // abbrev
if (force || ((config.options.chkAllowBrowserCookies || name=="chkAllowBrowserCookies")
&& !cmc.blockedCookies.contains(name) && cmc.allowBrowserCookie(name))) {
cmc.saveOptionCookie.apply(this,arguments);
cmc.displayStatus(name+"="+config.options[name]);
} else cmc.displayStatus("setting of '"+name+"' is blocked");
}
// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
window.removeCookie=function(name) {
document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
}
}
// ... and then hijack it to add cookie blocking and monitoring messages
config.macros.cookieManager.removeCookie=removeCookie;
window.removeCookie=function(name,force)
{
var cmc=config.macros.cookieManager; // abbrev
if (!cmc.getCookieList().contains(name))
return; // not a current cookie!
if (force || ((config.options.chkAllowBrowserCookies || name=="chkAllowBrowserCookies")
&& !cmc.blockedCookies.contains(name) && cmc.allowBrowserCookie(name))) {
cmc.removeCookie.apply(this,arguments);
cmc.displayStatus("deleted "+name);
} else cmc.displayStatus("deletion of '"+name+"' is blocked");
}
//}}}
/***
|Name|CookieManagerPluginConfig|
|Source|http://www.TiddlyTools.com/#CookieManagerPluginConfig|
|Requires|CookieManagerPlugin|
|Description|custom settings for [[CookieManagerPlugin]]|
!!!!!Browser Cookie Configuration:
***/
// // <<option chkAllowBrowserCookies>> store ~TiddlyWiki option settings using private browser cookies
// // <<option chkMonitorBrowserCookies>> monitor browser cookie activity (shows a message whenever a cookie is updated)
//{{{
// default settings:
config.options.chkAllowBrowserCookies=true; // if FALSE, this blocks *all* cookies
config.options.chkMonitorBrowserCookies=false;
//}}}
// // Individual cookie names can be prevented from being created, modified, or deleted in your browser's stored cookies by adding them to the {{{config.macros.cookieManager.blockedCookies}}} array:
//{{{
var bc=config.macros.cookieManager.blockedCookies; // abbreviation
bc.push("txtMainTab"); // TiddlyWiki: SideBarTabs
bc.push("txtTOCSortBy"); // TiddlyTools: TableOfContentsPlugin
bc.push("txtCatalogTab"); // TiddlyTools: ShowCatalog
//}}}
// // You can also define a javascript test function that determines whether or not any particular cookie name should be blocked or allowed. The following function should return FALSE if the browser cookie should be blocked, or TRUE if changes to the cookie should be allowed:
//{{{
config.macros.cookieManager.allowBrowserCookie=function(name) {
// add tests based on specific cookie names and runtime conditions
return true;
}
//}}}
/***
|Name|CopyTiddlerPlugin|
|Source|http://www.TiddlyTools.com/#CopyTiddlerPlugin|
|Version|3.2.4|
|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.3|
|Type|plugin|
|Requires||
|Overrides||
|Description|Quickly create a copy of any existing tiddler|
!!!Usage
<<<
This plugin automatically updates the default (shadow) ToolbarCommands slice definitions to insert the ''copyTiddler'' command (which appears as ''copy'' in the tiddler toolbar).
When you select the ''copy'' command, a new tiddler is opened with a title of "{{{TiddlerName (n)}}}" containing copies of the text/tags/fields from the original //source tiddler//, where ''(n)'' is the next available number (starting with 1, of course). Note: If you copy while //editing// a tiddler, the current values that are displayed in the existing tiddler editor are used (including any unsaved changes you may have made to those values), and the new tiddler is immediately opened for editing.
Note: if you are already using customized toolbar definitions, you will need to manually add the ''copyTiddler'' toolbar command to your existing ToolbarCommands tiddler, e.g.:
{{{
|EditToolbar|... copyTiddler ... |
}}}
The plugin also provides a macro that allows you to embed a ''copy'' command directly in specific tiddler content:
{{{
<<copyTiddler TidderName label:"..." prompt:"...">>
}}}
where
* ''TiddlerName'' (optional)<br>specifies the //source// tiddler to be copied. If omitted, the current containing tiddler (if any) will be copied.
* ''label:"..."'' (optional)<br>specifies text to use for the embedded link (default="copy TiddlerName")
* ''prompt:"..."'' (optional)<br>specifies mouseover 'tooltip' help text for link
//Note: to use non-default label/prompt values with the current containing tiddler, use "" for the TiddlerName//
<<<
!!!Revisions
<<<
2009.03.09 [3.2.4] fixed IE-specific syntax error
2009.03.02 [3.2.3] refactored code (again) to restore use of config.commands.copyTiddler.* custom settings
2009.02.13 [3.2.2] in click(), fix calls to displayTiddler() to use current tiddlerElem and use getTiddlerText() to permit copying of shadow tiddler content
2009.01.30 [3.2.1] fixed handling for copying field values when in edit mode
2009.01.23 [3.2.0] refactored code and added {{{<<copyTiddler TiddlerName>>}}} macro
2008.12.18 [3.1.4] corrected code for finding next (n) value when 'sparse' handling is in effect (thanks to RussThomas for identifying and diagnosing the problem)
2008.11.14 [3.1.3] added optional 'sparse' setting (avoids 'filling in' missing numbers that may have been previously deleted)
2008.11.14 [3.1.2] added optional 'zeroPad' setting
2008.11.14 [3.1.1] moved hard-coded '(n)' regex into 'suffixPattern' object property so it can be customized
2008.09.26 [3.1.0] changed new title generation to use '(n)' suffix instead of 'Copy of' prefix
2008.05.20 [3.0.3] in handler, when copying from VIEW mode, create duplicate array from existing tags array before saving new tiddler.
2007.12.19 [3.0.2] in handler, when copying from VIEW mode, duplicate custom fields before saving new tiddler. Thanks to bug report from Ken Girard.
2007.09.26 [3.0.1] in handler, use findContainingTiddler(src) to get tiddlerElem (and title). Allows 'copy' command to find correct tiddler when transcluded using {{{<<tiddler>>}}} macro or enhanced toolbar inclusion (see [[CoreTweaks]])
2007.06.28 [3.0.0] complete re-write to handle custom fields and alternative view/edit templates
2007.05.17 [2.1.2] use store.getTiddlerText() to retrieve tiddler content, so that SHADOW tiddlers can be copied correctly when in VIEW mode
2007.04.01 [2.1.1] in copyTiddler.handler(), fix check for editor fields by ensuring that found field actually has edit=='text' attribute
2007.02.05 [2.1.0] in copyTiddler.handler(), if editor fields (textfield and/or tagsfield) can't be found (i.e., tiddler is in VIEW mode, not EDIT mode), then get text/tags values from stored tiddler instead of active editor fields. Allows use of COPY toolbar directly from VIEW mode (based on a request from LaurentCharles)
2006.12.12 [2.0.0] completely rewritten so plugin just creates a new tiddler EDITOR with a copy of the current tiddler EDITOR contents, instead of creating the new tiddler in the STORE by copying the current tiddler values from the STORE.
2005.xx.xx [1.0.0] original version by Tim Morgan
<<<
!!!Code
***/
//{{{
version.extensions.CopyTiddlerPlugin= {major: 3, minor: 2, revision: 4, date: new Date(2009,3,9)};
// automatically tweak shadow EditTemplate to add 'copyTiddler' toolbar command (following 'cancelTiddler')
config.shadowTiddlers.ToolbarCommands=config.shadowTiddlers.ToolbarCommands.replace(/cancelTiddler/,'cancelTiddler copyTiddler');
config.commands.copyTiddler = {
text: 'copy',
hideReadOnly: true,
tooltip: 'Make a copy of this tiddler',
notitle: 'this tiddler',
prefix: '',
suffixText: ' (%0)',
suffixPattern: / \(([0-9]+)\)$/,
zeroPad: 0,
sparse: false,
handler: function(event,src,title)
{ return config.commands.copyTiddler.click(src,event); },
click: function(here,ev) {
var tiddlerElem=story.findContainingTiddler(here);
var template=tiddlerElem?tiddlerElem.getAttribute('template'):null;
var title=here.getAttribute('from');
if (!title || !title.length) {
if (!tiddlerElem) return false;
else title=tiddlerElem.getAttribute('tiddler');
}
var root=title.replace(this.suffixPattern,''); // title without suffix
// find last matching title
var last=title;
if (this.sparse) { // don't fill-in holes... really find LAST matching title
var tids=store.getTiddlers('title','excludeLists');
for (var t=0; t<tids.length; t++) if (tids[t].title.startsWith(root)) last=tids[t].title;
}
// get next number (increment from last matching title)
var n=1; var match=this.suffixPattern.exec(last); if (match) n=parseInt(match[1])+1;
var newTitle=this.prefix+root+this.suffixText.format([String.zeroPad(n,this.zeroPad)]);
// if not sparse mode, find the next hole to fill in...
while (store.tiddlerExists(newTitle)||document.getElementById(story.idPrefix+newTitle))
{ n++; newTitle=this.prefix+root+this.suffixText.format([String.zeroPad(n,this.zeroPad)]); }
if (!story.isDirty(title)) { // if tiddler is not being EDITED
// duplicate stored tiddler (if any)
var text=store.getTiddlerText(title,'');
var newtags=[]; var newfields={};
var tid=store.getTiddler(title); if (tid) {
for (var t=0; t<tid.tags.length; t++) newtags.push(tid.tags[t]);
store.forEachField(tid,function(t,f,v){newfields[f]=v;},true);
}
store.saveTiddler(newTitle,newTitle,text,
config.options.txtUserName,new Date(),newtags, newfields, true); // clear changecount
story.displayTiddler(tiddlerElem,newTitle,template);
} else {
story.displayTiddler(tiddlerElem,newTitle,template);
var fields=config.commands.copyTiddler.gatherFields(tiddlerElem); // get current editor fields
var newTiddlerElem=document.getElementById(story.idPrefix+newTitle);
for (var f=0; f<fields.length; f++) { // set fields in new editor
if (fields[f].name=='title') fields[f].value=newTitle; // rename title in new tiddler
var fieldElem=config.commands.copyTiddler.findField(newTiddlerElem,fields[f].name);
if (fieldElem) {
if (fieldElem.getAttribute('type')=='checkbox')
fieldElem.checked=fields[f].value;
else
fieldElem.value=fields[f].value;
}
}
}
story.focusTiddler(newTitle,'title');
return false;
},
findField: function(tiddlerElem,field) {
var inputs=tiddlerElem.getElementsByTagName('input');
for (var i=0; i<inputs.length; i++) {
if (inputs[i].getAttribute('type')=='checkbox' && inputs[i].field == field) return inputs[i];
if (inputs[i].getAttribute('type')=='text' && inputs[i].getAttribute('edit') == field) return inputs[i];
}
var tas=tiddlerElem.getElementsByTagName('textarea');
for (var i=0; i<tas.length; i++) if (tas[i].getAttribute('edit') == field) return tas[i];
var sels=tiddlerElem.getElementsByTagName('select');
for (var i=0; i<sels.length; i++) if (sels[i].getAttribute('edit') == field) return sels[i];
return null;
},
gatherFields: function(tiddlerElem) { // get field names and values from current tiddler editor
var fields=[];
// get checkboxes and edit fields
var inputs=tiddlerElem.getElementsByTagName('input');
for (var i=0; i<inputs.length; i++) {
if (inputs[i].getAttribute('type')=='checkbox')
if (inputs[i].field) fields.push({name:inputs[i].field,value:inputs[i].checked});
if (inputs[i].getAttribute('type')=='text')
if (inputs[i].getAttribute('edit')) fields.push({name:inputs[i].getAttribute('edit'),value:inputs[i].value});
}
// get textareas (multi-line edit fields)
var tas=tiddlerElem.getElementsByTagName('textarea');
for (var i=0; i<tas.length; i++)
if (tas[i].getAttribute('edit')) fields.push({name:tas[i].getAttribute('edit'),value:tas[i].value});
// get selection lists (droplist or listbox)
var sels=tiddlerElem.getElementsByTagName('select');
for (var i=0; i<sels.length; i++)
if (sels[i].getAttribute('edit')) fields.push({name:sels[i].getAttribute('edit'),value:sels[i].value});
return fields;
}
};
//}}}
// // MACRO DEFINITION
//{{{
config.macros.copyTiddler = {
label: 'copy',
prompt: 'Make a copy of %0',
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var title=params.shift();
params=paramString.parseParams('anon',null,true,false,false);
var label =getParam(params,'label',this.label+(title?' '+title:''));
var prompt =getParam(params,'prompt',this.prompt).format([title||this.notitle]);
var b=createTiddlyButton(place,label,prompt,
function(ev){return config.commands.copyTiddler.click(this,ev)});
b.setAttribute('from',title||'');
}
};
//}}}
/***
|Name|CoreTweaks|
|Source|http://www.TiddlyTools.com/#CoreTweaks|
|Version|use with TW2.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.2.0|
|Type|plugin|
|Requires||
|Overrides|various|
|Description|a small collection of overrides to TW core functions|
This tiddler contains changes TW core functions to provide minor changes in standard features or behavior. It is hoped that some of these tweaks may someday be added into the TW core, so that these adjustments will be available without needing these add-on definitions.
>''Note: the changes contained in this tiddler are generally applicable for version 2.4.3 of TiddlyWiki.''
>Please view [[CoreTweaksArchive]] for tweaks that may be used with earlier versions of TiddlyWiki.
***/
//{{{
// calculate TW version number - used to determine which tweaks should be applied
var ver=version.major+version.minor/10+version.revision/100;
//}}}
/***
----
***/
// // open tickets:
// // {{block{
/***
!!!890 add conditional test to """<<tiddler>>""" macro
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/890 - OPEN
This tweak extends the {{{<<tiddler>>}}} macro syntax so you can include a javascript-based //test expression// to determine if the tiddler transclusion should be performed:
{{{
<<tiddler TiddlerName if:{{...}} with: param param etc.>>
}}}
If the test is ''true'', then the tiddler is transcluded as usual. If the test is ''false'', then the transclusion is skipped and //no output is produced//.
***/
//{{{
config.macros.tiddler.if_handler = config.macros.tiddler.handler;
config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
params = paramString.parseParams('name',null,true,false,true);
if (!getParam(params,'if',true)) return;
this.if_handler.apply(this,arguments);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!831 backslash-quoting for embedding newlines in 'line-mode' formats
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/831 - OPEN
This tweak pre-processes source content to convert 'double-backslash-newline' into {{{<br>}}} before wikify(), so that literal newlines can be embedded in line-mode wiki syntax (e.g., tables, bullets, etc.)
***/
//{{{
window.coreWikify = wikify;
window.wikify = function(source,output,highlightRegExp,tiddler)
{
if (source) arguments[0]=source.replace(/\\\\\n/mg,'<br>');
coreWikify.apply(this,arguments);
}
//}}}
// // }}}}}}// // {{block{
/***
!!!829 """<<tag>>""" macro - sortby parameter
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/829 - OPEN
This tweak adds an optional 'sortby' parameter to the """<<tag tagname label tip sortby>>""" macro, as well as the """<<allTags excludeTag sortby>>""" macro used to generate the sidebar contents 'tags' list. Specify the field on which the contents of each tag popup is to be sorted, with a '+' or '-' prefix to indicate ascending/descending order, respectively.
Example: """<<tag systemConfig "plugins" "list plugins by date, most recent first" "-modified">>"""
Try it: <<tag systemConfig "plugins" "list plugins by date, most recent first" "-modified">>
Similarly, to change the sort order used by the popups from all tags shown in the sidebar contents, edit the [[TagTags]] shadow tiddler and enter: """<<allTags excludeLists -modified>>"""
***/
//{{{
// hijack tag handler() to add 'sortby' attribute to tag button
config.macros.tag.CoreTweaksSortTags_handler=config.macros.tag.handler;
config.macros.tag.handler = function(place,macroName,params)
{
this.CoreTweaksSortTags_handler.apply(this,arguments);
var btn=place.lastChild;
if (params[3]) btn.setAttribute('sortby',params[3]);
}
// tweak <<allTags>> macro to add 'sortby' attribute to each tag button
var fn=config.macros.allTags.handler;
var lines=fn.toString().split('\n');
lines.splice(lines.length-2,0,['if(params[1]) btn.setAttribute("sortby",params[1]);']);
fn=lines.join('\n');
eval('config.macros.allTags.handler='+fn);
// tweak tag event handler to:
// * use tag filtering (only if '[' is present in tag value)
// * use optional 'sortby' attribute
// * save 'sortby' value in 'open all' command (for displaying tiddlers in sorted order)
var fn=onClickTag;
fn=fn.toString().replace(
/store.getTaggedTiddlers\(tag\);/g,
'(tag.indexOf("[")==-1?store.getTaggedTiddlers(tag):store.filterTiddlers(tag));'
+'var sortby=this.getAttribute("sortby");'
+'if(sortby&&sortby.length) store.sortTiddlers(tagged,sortby);'
);
fn=fn.toString().replace(
/openAll.setAttribute\("tag",\s*tag\);/g,
'openAll.setAttribute("tag",tag); openAll.setAttribute("sortby",sortby);'
);
eval(fn);
// tweak 'open all' event handler to use 'sortby' attribute
var fn=onClickTagOpenAll;
fn=fn.toString().replace(
/story.displayTiddlers\(this,\s*tiddlers\);/g,
'var sortby=this.getAttribute("sortby");'
+'if(sortby&&sortby.length) store.sortTiddlers(tiddlers,sortby);'
+'story.displayTiddlers(this,tiddlers);'
);
eval(fn);
//}}}
// // }}}}}}// // {{block{
/***
!!!824 ~WindowTitle - alternative to combined ~SiteTitle/~SiteSubtitle in window titlebar
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/824 - OPEN
This tweak allows definition of an optional [[WindowTitle]] tiddler that, when present, provides alternative text for display in the browser window's titlebar, instead of using the combined text content from [[SiteTitle]] and [[SiteSubtitle]] (which will still be displayed as usual in the TiddlyWiki document header area).
Note: this ticket replaces http://trac.tiddlywiki.org/ticket/401 (closed), which proposed using a custom [[PageTitle]] tiddler for this purpose. ''If you were using the previous '401 ~PageTitle' tweak, you will need to rename [[PageTitle]] to [[WindowTitle]] to continue to use your custom window title text''
***/
//{{{
config.shadowTiddlers.WindowTitle='<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>';
window.getPageTitle=function() { return wikifyPlain('WindowTitle'); }
store.addNotification('WindowTitle',refreshPageTitle); // so title stays in sync with tiddler changes
//}}}
// // }}}}}}// // {{block{
/***
!!!784 allow tiddler sections in TiddlyLinks to be used as anchor points for intra-tiddler scrolling.
>http://trac.tiddlywiki.org/ticket/784 - OPEN - Please see separate [[SectionLinksPlugin]]
!!!683 FireFox3 Import bug: 'browse' button replacement
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/683 - OPEN
The web standard 'type=file' input control that has been used as a local path/file picker for TiddlyWiki no longer works as expected in FireFox3, which has, for security reasons, limited javascript access to this control so that *no* local filesystem path information can be revealed, even when it is intentional and necessary, as it is with TiddlyWiki. This tweak provides alternative HTML source that patches the backstage import panel. It replaces the 'type=file' input control with a text+button combination of controls that invokes a system-native secure 'file-chooser' dialog box to provide TiddlyWiki with access to a complete path+filename so that TW functions properly locate user-selected local files.
>Note: ''This tweak also requires http://trac.tiddlywiki.org/ticket/604 - cross-platform askForFilename()''
***/
//{{{
if (window.Components) {
var fixhtml='<input name="txtBrowse" style="width:30em"><input type="button" value="..."'
+' onClick="window.browseForFilename(this.previousSibling,true)">';
var cmi=config.macros.importTiddlers;
cmi.step1Html=cmi.step1Html.replace(/<input type='file' size=50 name='txtBrowse'>/,fixhtml);
}
merge(config.messages,{selectFile:'Please enter or select a file'}); // ready for I18N translation
window.browseForFilename=function(target,mustExist) { // note: both params are optional
var msg=config.messages.selectFile;
if (target && target.title) msg=target.title; // use target field tooltip (if any) as dialog prompt text
// get local path for current document
var path=getLocalPath(document.location.href);
var p=path.lastIndexOf('/'); if (p==-1) p=path.lastIndexOf('\\'); // Unix or Windows
if (p!=-1) path=path.substr(0,p+1); // remove filename, leave trailing slash
var file=''
var result=window.askForFilename(msg,path,file,mustExist); // requires #604
if (target && result.length) // set target field and trigger handling
{ target.value=result; target.onchange(); }
return result;
}
//}}}
// // }}}}}}// // {{block{
/***
!!!604 cross-platform askForFilename()
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/604 - OPEN
invokes a system-native secure 'file-chooser' dialog box to provide TiddlyWiki with access to a complete path+filename so that TW functions properly locate user-selected local files.
***/
//{{{
window.askForFilename=function(msg,path,file,mustExist) {
var r = window.mozAskForFilename(msg,path,file,mustExist);
if(r===null || r===false)
r = window.ieAskForFilename(msg,path,file,mustExist);
if(r===null || r===false)
r = window.javaAskForFilename(msg,path,file,mustExist);
if(r===null || r===false)
r = prompt(msg,path+file);
return r||'';
}
window.mozAskForFilename=function(msg,path,file,mustExist) {
if(!window.Components) return false;
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, mustExist?nsIFilePicker.modeOpen:nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='html';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel)
var result=picker.file.persistentDescriptor;
}
catch(ex) { displayMessage(ex.toString()); }
return result;
}
window.ieAskForFilename=function(msg,path,file,mustExist) {
if(!config.browser.isIE) return false;
try {
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
s.FilterIndex=3; // default to HTML files;
s.InitialDir=path;
s.FileName=file;
return s.showOpen()?s.FileName:'';
}
catch(ex) { displayMessage(ex.toString()); }
return result;
}
window.javaAskForFilename=function(msg,path,file,mustExist) {
if(!document.applets['TiddlySaver']) return false;
// TBD: implement java-based askFile(...) function
try { return document.applets['TiddlySaver'].askFile(msg,path,file,mustExist); }
catch(ex) { displayMessage(ex.toString()); }
}
//}}}
// // }}}}}}// // {{block{
/***
!!!657 wrap tabs onto multiple lines
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/657 - OPEN
This tweak inserts an extra space element following each tab, allowing them to wrap onto multiple lines if needed.
***/
//{{{
config.macros.tabs.handler = function(place,macroName,params)
{
var cookie = params[0];
var numTabs = (params.length-1)/3;
var wrapper = createTiddlyElement(null,'div',null,'tabsetWrapper ' + cookie);
var tabset = createTiddlyElement(wrapper,'div',null,'tabset');
tabset.setAttribute('cookie',cookie);
var validTab = false;
for(var t=0; t<numTabs; t++) {
var label = params[t*3+1];
var prompt = params[t*3+2];
var content = params[t*3+3];
var tab = createTiddlyButton(tabset,label,prompt,this.onClickTab,'tab tabUnselected');
createTiddlyElement(tab,'span',null,null,' ',{style:'font-size:0pt;line-height:0px'}); // ELS
tab.setAttribute('tab',label);
tab.setAttribute('content',content);
tab.title = prompt;
if(config.options[cookie] == label)
validTab = true;
}
if(!validTab)
config.options[cookie] = params[1];
place.appendChild(wrapper);
this.switchTab(tabset,config.options[cookie]);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!628 hide 'no such macro' errors
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/628 - OPEN
When invoking a macro that is not defined, this tweak prevents the display of the 'error in macro... no such macro' message. This is useful when rendering tiddler content or templates that reference macros that are defined by //optional// plugins that have not been installed in the current document.
<<option chkHideMissingMacros>> hide 'no such macro' error messages
***/
//{{{
if (config.options.chkHideMissingMacros===undefined)
config.options.chkHideMissingMacros=false;
window.coreTweaks_missingMacro_invokeMacro = window.invokeMacro;
window.invokeMacro = function(place,macro,params,wikifier,tiddler) {
if (!config.macros[macro] || !config.macros[macro].handler)
if (config.options.chkHideMissingMacros) return;
window.coreTweaks_missingMacro_invokeMacro.apply(this,arguments);
}
//}}}
// // }}}}}}// // {{block{
/***
!!!608/609/610 toolbars - toggles, separators and transclusion
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/608 - OPEN (more/less toggle)
http://trac.tiddlywiki.org/ticket/609 - OPEN (separators)
http://trac.tiddlywiki.org/ticket/610 - OPEN (wikify tiddler/slice/section content)
This combination tweak extends the """<<toolbar>>""" macro to add use of '<' to insert a 'less' menu command (the opposite of '>' == 'more'), as well as use of '*' to insert linebreaks and "!" to insert a vertical line separator between toolbar items. In addition, this tweak add the ability to use references to tiddlernames, slices, or sections and render their content inline within the toolbar, allowing easy creation of new toolbar commands using TW content (such as macros, links, inline scripts, etc.)
To produce a one-line style, with "less" at the end, use
| ViewToolbar| foo bar baz > yabba dabba doo < |
resulting in:
{{{
foo bar baz more
and
foo bar baz yabba dabba doo less
}}}
or to use the CoreTweaks? two-line style:
| ViewToolbar| foo bar baz > < * yabba dabba doo |
which would produce:
{{{
foo bar baz more
and
foo bar baz less
yabba dabba doo
}}}
''see [[ToolbarCommands]] for examples of how these features can be used''
***/
//{{{
merge(config.macros.toolbar,{
moreLabel: 'more\u25BC',
morePrompt: 'Show additional commands',
lessLabel: '\u25C4less',
lessPrompt: 'Hide additional commands',
separator: '|'
});
config.macros.toolbar.onClickMore = function(ev) {
var e = this.nextSibling;
e.style.display = 'inline'; // show menu
this.style.display = 'none'; // hide button
return false;
};
config.macros.toolbar.onClickLess = function(ev) {
var e = this.parentNode;
var m = e.previousSibling;
e.style.display = 'none'; // hide menu
m.style.display = 'inline'; // show button
return false;
};
config.macros.toolbar.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
for(var t=0; t<params.length; t++) {
var c = params[t];
switch(c) {
case '!': // ELS - SEPARATOR (added)
createTiddlyText(place,this.separator);
break;
case '*': // ELS - LINEBREAK (added)
createTiddlyElement(place,'BR');
break;
case '<': // ELS - LESS COMMAND (added)
var btn = createTiddlyButton(place,
this.lessLabel,this.lessPrompt,config.macros.toolbar.onClickLess,'moreCommand');
break;
case '>':
var btn = createTiddlyButton(place,
this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore,'moreCommand');
var e = createTiddlyElement(place,'span',null,'moreCommand');
e.style.display = 'none';
place = e;
break;
default:
var theClass = '';
switch(c.substr(0,1)) {
case '+':
theClass = 'defaultCommand';
c = c.substr(1);
break;
case '-':
theClass = 'cancelCommand';
c = c.substr(1);
break;
}
if(c in config.commands)
this.createCommand(place,c,tiddler,theClass);
else { // ELS - WIKIFY TIDDLER/SLICE/SECTION (added)
if (c.substr(0,1)=='~') c=c.substr(1); // ignore leading ~
var txt=store.getTiddlerText(c);
if (txt) {
// trim any leading/trailing newlines
txt=txt.replace(/^\n*/,'').replace(/\n*$/,'');
// trim PRE format wrapper if any
txt=txt.replace(/^\{\{\{\n/,'').replace(/\n\}\}\}$/,'');
// render content into toolbar
wikify(txt,createTiddlyElement(place,'span'),null,tiddler);
}
} // ELS - end WIKIFY CONTENT
break;
}
}
};
//}}}
// // }}}}}}// // {{block{
/***
!!!529 IE fixup - case-sensitive element lookup of tiddler elements
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/529 - OPEN
This tweak hijacks the standard browser function, document.getElementById(), to work-around the case-INsensitivity error in Internet Explorer (all versions up to and including IE7) //''Note: This tweak is only applied when using IE, and only for lookups of rendered tiddler elements within the containing 'tiddlerDisplay' element.''//
***/
//{{{
if (config.browser.isIE) {
document.coreTweaks_coreGetElementById=document.getElementById;
document.getElementById=function(id) {
var e=document.coreTweaks_coreGetElementById(id);
if (!e || !e.parentNode || e.parentNode.id!='tiddlerDisplay') return e;
for (var i=0; i<e.parentNode.childNodes.length; i++)
if (id==e.parentNode.childNodes[i].id) return e.parentNode.childNodes[i];
return null;
};
}
//}}}
// // }}}}}}// // {{block{
/***
!!!471 'creator' field for new tiddlers
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/471 - OPEN
This tweak HIJACKS the core's saveTiddler() function to automatically add a 'creator' field to a tiddler when it is FIRST created. You can use """<<view creator>>""" (or """<<view creator wikified>>""" if you prefer) to show this value embedded directly within the tiddler content, or {{{<span macro="view creator"></span>}}} in the ViewTemplate and/or EditTemplate to display the creator value in each tiddler.
***/
//{{{
// hijack saveTiddler()
TiddlyWiki.prototype.CoreTweaks_creatorSaveTiddler=TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler=function(title,newTitle,newBody,modifier,modified,tags,fields)
{
var existing=store.tiddlerExists(title);
var tiddler=this.CoreTweaks_creatorSaveTiddler.apply(this,arguments);
if (!existing) store.setValue(title,'creator',config.options.txtUserName);
return tiddler;
}
//}}}
// // }}}}}}
// // closed: won't fix //(leave as core tweaks)//
// // {{block{
/***
!!!637 TiddlyLink tooltip - custom formatting
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/637 - CLOSED: WON'T FIX
This tweak modifies the tooltip format that appears when you mouseover a link to a tiddler. It adds an option to control the date format, as well as displaying the size of the tiddler (in bytes)
Tiddler link tooltip format:
{{stretch{<<option txtTiddlerLinkTootip>>}}}
^^where: %0=title, %1=username, %2=modification date, %3=size in bytes, %4=description slice^^
Tiddler link tooltip date format:
{{stretch{<<option txtTiddlerLinkTooltipDate>>}}}
***/
//{{{
config.messages.tiddlerLinkTooltip='%0 - %1, %2 (%3 bytes) - %4';
config.messages.tiddlerLinkTooltipDate='DDD, MMM DDth YYYY 0hh12:0mm AM';
config.options.txtTiddlerLinkTootip=
config.options.txtTiddlerLinkTootip||config.messages.tiddlerLinkTooltip;
config.options.txtTiddlerLinkTooltipDate=
config.options.txtTiddlerLinkTooltipDate||config.messages.tiddlerLinkTooltipDate;
Tiddler.prototype.getSubtitle = function() {
var modifier = this.modifier;
if(!modifier) modifier = config.messages.subtitleUnknown;
var modified = this.modified;
if(modified) modified = modified.formatString(config.options.txtTiddlerLinkTooltipDate);
else modified = config.messages.subtitleUnknown;
var descr=store.getTiddlerSlice(this.title,'Description')||'';
return config.options.txtTiddlerLinkTootip.format([this.title,modifier,modified,this.text.length,descr]);
};
//}}}
// // }}}}}}// // {{block{
/***
!!!607 add HREF link on permaview command
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/607 - CLOSED: WON'T FIX
This tweak automatically sets the HREF for the 'permaview' sidebar command link so you can use the 'right click' context menu for faster, easier bookmarking. Note that this does ''not'' automatically set the permaview in the browser's current location URL... it just sets the HREF on the command link. You still have to click the link to apply the permaview.
***/
//{{{
config.macros.permaview.handler = function(place)
{
var btn=createTiddlyButton(place,this.label,this.prompt,this.onClick);
addEvent(btn,'mouseover',this.setHREF);
addEvent(btn,'focus',this.setHREF);
};
config.macros.permaview.setHREF = function(event){
var links = [];
story.forEachTiddler(function(title,element) {
links.push(String.encodeTiddlyLink(title));
});
var newURL=document.location.href;
var hashPos=newURL.indexOf('#');
if (hashPos!=-1) newURL=newURL.substr(0,hashPos);
this.href=newURL+'#'+encodeURIComponent(links.join(' '));
}
//}}}
// // }}}}}}// // {{block{
/***
!!!458 add permalink-like HREFs on internal TiddlyLinks
***/
// // {{groupbox small{
/***
http://trac.tiddlywiki.org/ticket/458 - CLOSED: WON'T FIX
This tweak assigns a permalink-like HREF to internal Tiddler links (which normally do not have any HREF defined). This permits the link's context menu (right-click) to include 'open link in another window/tab' command. Based on a request from Dustin Spicuzza.
***/
//{{{
window.coreTweaks_createTiddlyLink=window.createTiddlyLink;
window.createTiddlyLink=function(place,title,includeText,theClass,isStatic,linkedFromTiddler,noToggle)
{
// create the core button, then add the HREF (to internal links only)
var link=window.coreTweaks_createTiddlyLink.apply(this,arguments);
if (!isStatic)
link.href=document.location.href.split('#')[0]+'#'+encodeURIComponent(String.encodeTiddlyLink(title));
return link;
}
//}}}
// // }}}}}}
// // <<foldHeadings>>
/%
***** PLEASE DO NOT DELETE THIS CONTENT *****
%/''~TiddlyBlog'' //document design and functionality created by://
[[Eric L Shulman|http://about.unamesa.org/Eric+Shulman]] - [[TiddlyTools / ELS Design Studios|http://www.TiddlyTools.com]] ''//"Small Tools for Big Ideas!"™//''
with thanks to Paul Reiber of [[Reiber Labs|http://reiber.org]]
data://image/jpeg;base64,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
/***
|Name|DatePlugin|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.7.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||
|Overrides||
|Options|##Configuration|
|Description|formatted dates plus popup menu with 'journal' link, changes and (optional) reminders|
There are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW. While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier. This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.
!!!!!Documentation
>see [[DatePluginInfo]]
!!!!!Configuration
<<<
<<option chkDatePopupHideCreated>> omit 'created' section from date popups
<<option chkDatePopupHideChanged>> omit 'changed' section from date popups
<<option chkDatePopupHideTagged>> omit 'tagged' section from date popups
<<option chkDatePopupHideReminders>> omit 'reminders' section from date popups
<<option chkShowJulianDate>> display Julian day number (1-365) below current date
see [[DatePluginConfig]] for additional configuration settings, for use in calendar displays, including:
*date formats
*color-coded backgrounds
*annual fixed-date holidays
*weekends
<<<
!!!!!Revisions
<<<
2008.03.08 [2.7.0] in addModifiedsToPopup(), if a tiddler was created on the specified date, don't list it in the 'changed' section of the popup. Based on a request from Kashgarinn.
|please see [[DatePluginInfo]] for additional revision details|
2005.10.30 [0.9.0] pre-release
<<<
!!!!!Code
***/
//{{{
version.extensions.DatePlugin= {major: 2, minor: 7, revision: 0, date: new Date(2008,3,8)};
config.macros.date = {
format: "YYYY.0MM.0DD", // default date display format
linkformat: "YYYY.0MM.0DD", // 'dated tiddler' link format
linkedbg: "#babb1e", // "babble"
todaybg: "#ffab1e", // "fable"
weekendbg: "#c0c0c0", // "cocoa"
holidaybg: "#ffaace", // "face"
createdbg: "#bbeeff", // "beef"
modifiedsbg: "#bbeeff", // "beef"
remindersbg: "#c0ffee", // "coffee"
holidays: [ "01/01", "07/04", "07/24", "11/24" ], // NewYearsDay, IndependenceDay(US), Eric's Birthday (hooray!), Thanksgiving(US)
weekend: [ 1,0,0,0,0,0,1 ] // [ day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 ]
};
config.macros.date.handler = function(place,macroName,params)
{
// do we want to see a link, a popup, or just a formatted date?
var mode="display";
if (params[0]=="display") { mode=params[0]; params.shift(); }
if (params[0]=="popup") { mode=params[0]; params.shift(); }
if (params[0]=="link") { mode=params[0]; params.shift(); }
// get the date
var now = new Date();
var date = now;
if (!params[0] || params[0]=="today")
{ params.shift(); }
else if (params[0]=="filedate")
{ date=new Date(document.lastModified); params.shift(); }
else if (params[0]=="tiddler")
{ date=store.getTiddler(story.findContainingTiddler(place).id.substr(7)).modified; params.shift(); }
else if (params[0].substr(0,8)=="tiddler:")
{ var t; if ((t=store.getTiddler(params[0].substr(8)))) date=t.modified; params.shift(); }
else {
var y = eval(params.shift().replace(/Y/ig,(now.getYear()<1900)?now.getYear()+1900:now.getYear()));
var m = eval(params.shift().replace(/M/ig,now.getMonth()+1));
var d = eval(params.shift().replace(/D/ig,now.getDate()+0));
date = new Date(y,m-1,d);
}
// date format with optional custom override
var format=this.format; if (params[0]) format=params.shift();
var linkformat=this.linkformat; if (params[0]) linkformat=params.shift();
showDate(place,date,mode,format,linkformat);
}
window.showDate=showDate;
function showDate(place,date,mode,format,linkformat,autostyle,weekend)
{
if (!mode) mode="display";
if (!format) format=config.macros.date.format;
if (!linkformat) linkformat=config.macros.date.linkformat;
if (!autostyle) autostyle=false;
// format the date output
var title = date.formatString(format);
var linkto = date.formatString(linkformat);
// just show the formatted output
if (mode=="display") { place.appendChild(document.createTextNode(title)); return; }
// link to a 'dated tiddler'
var link = createTiddlyLink(place, linkto, false);
link.appendChild(document.createTextNode(title));
link.title = linkto;
link.date = date;
link.format = format;
link.linkformat = linkformat;
// if using a popup menu, replace click handler for dated tiddler link
// with handler for popup and make link text non-italic (i.e., an 'existing link' look)
if (mode=="popup") {
link.onclick = onClickDatePopup;
link.style.fontStyle="normal";
}
// format the popup link to show what kind of info it contains (for use with calendar generators)
if (autostyle) setDateStyle(place,link,weekend);
}
//}}}
//{{{
// NOTE: This function provides default logic for setting the date style when displayed in a calendar
// To customize the date style logic, please see[[DatePluginConfig]]
function setDateStyle(place,link,weekend) {
// alias variable names for code readability
var date=link.date;
var fmt=link.linkformat;
var linkto=date.formatString(fmt);
var cmd=config.macros.date;
if ((weekend!==undefined?weekend:isWeekend(date))&&(cmd.weekendbg!=""))
{ place.style.background = cmd.weekendbg; }
if (hasModifieds(date)||hasCreateds(date)||hasTagged(date,fmt))
{ link.style.fontStyle="normal"; link.style.fontWeight="bold"; }
if (hasReminders(date))
{ link.style.textDecoration="underline"; }
if (isToday(date))
{ link.style.border="1px solid black"; }
if (isHoliday(date)&&(cmd.holidaybg!=""))
{ place.style.background = cmd.holidaybg; }
if (hasCreateds(date)&&(cmd.createdbg!=""))
{ place.style.background = cmd.createdbg; }
if (hasModifieds(date)&&(cmd.modifiedsbg!=""))
{ place.style.background = cmd.modifiedsbg; }
if ((hasTagged(date,fmt)||store.tiddlerExists(linkto))&&(cmd.linkedbg!=""))
{ place.style.background = cmd.linkedbg; }
if (hasReminders(date)&&(cmd.remindersbg!=""))
{ place.style.background = cmd.remindersbg; }
if (isToday(date)&&(cmd.todaybg!=""))
{ place.style.background = cmd.todaybg; }
if (config.options.chkShowJulianDate) { // optional display of Julian date numbers
var m=[0,31,59,90,120,151,181,212,243,273,304,334];
var d=date.getDate()+m[date.getMonth()];
var y=date.getFullYear();
if (date.getMonth()>1 && (y%4==0 && y%100!=0) || y%400==0)
d++; // after February in a leap year
wikify("@@font-size:80%;<br>"+d+"@@",place);
}
}
//}}}
//{{{
function isToday(date) // returns true if date is today
{ var now=new Date(); return ((now-date>=0) && (now-date<86400000)); }
function isWeekend(date) // returns true if date is a weekend
{ return (config.macros.date.weekend[date.getDay()]); }
function isHoliday(date) // returns true if date is a holiday
{
var longHoliday = date.formatString("0MM/0DD/YYYY");
var shortHoliday = date.formatString("0MM/0DD");
for(var i = 0; i < config.macros.date.holidays.length; i++) {
var holiday=config.macros.date.holidays[i];
if (holiday==longHoliday||holiday==shortHoliday) return true;
}
return false;
}
//}}}
//{{{
// Event handler for clicking on a day popup
function onClickDatePopup(e)
{
if (!e) var e = window.event;
var theTarget = resolveTarget(e);
var popup = Popup.create(this);
if(popup) {
// always show dated tiddler link (or just date, if readOnly) at the top...
if (!readOnly || store.tiddlerExists(this.date.formatString(this.linkformat)))
createTiddlyLink(popup,this.date.formatString(this.linkformat),true);
else
createTiddlyText(popup,this.date.formatString(this.linkformat));
if (!config.options.chkDatePopupHideCreated)
addCreatedsToPopup(popup,this.date,this.format);
if (!config.options.chkDatePopupHideChanged)
addModifiedsToPopup(popup,this.date,this.format);
if (!config.options.chkDatePopupHideTagged)
addTaggedToPopup(popup,this.date,this.linkformat);
if (!config.options.chkDatePopupHideReminders)
addRemindersToPopup(popup,this.date,this.linkformat);
}
Popup.show(popup,false);
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
}
//}}}
//{{{
function indexCreateds() // build list of tiddlers, hash indexed by creation date
{
var createds= { };
var tiddlers = store.getTiddlers("title","excludeLists");
for (var t = 0; t < tiddlers.length; t++) {
var date = tiddlers[t].created.formatString("YYYY0MM0DD")
if (!createds[date])
createds[date]=new Array();
createds[date].push(tiddlers[t].title);
}
return createds;
}
function hasCreateds(date) // returns true if date has created tiddlers
{
if (!config.macros.date.createds) config.macros.date.createds=indexCreateds();
return (config.macros.date.createds[date.formatString("YYYY0MM0DD")]!=undefined);
}
function addCreatedsToPopup(popup,when,format)
{
var force=(store.isDirty() && when.formatString("YYYY0MM0DD")==new Date().formatString("YYYY0MM0DD"));
if (force || !config.macros.date.createds) config.macros.date.createds=indexCreateds();
var indent=String.fromCharCode(160)+String.fromCharCode(160);
var createds = config.macros.date.createds[when.formatString("YYYY0MM0DD")];
if (createds) {
createds.sort();
var e=createTiddlyElement(popup,"div",null,null,"created ("+createds.length+")");
for(var t=0; t<createds.length; t++) {
var link=createTiddlyLink(popup,createds[t],false);
link.appendChild(document.createTextNode(indent+createds[t]));
createTiddlyElement(popup,"br",null,null,null);
}
}
}
//}}}
//{{{
function indexModifieds() // build list of tiddlers, hash indexed by modification date
{
var modifieds= { };
var tiddlers = store.getTiddlers("title","excludeLists");
for (var t = 0; t < tiddlers.length; t++) {
var date = tiddlers[t].modified.formatString("YYYY0MM0DD")
if (!modifieds[date])
modifieds[date]=new Array();
modifieds[date].push(tiddlers[t].title);
}
return modifieds;
}
function hasModifieds(date) // returns true if date has modified tiddlers
{
if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();
return (config.macros.date.modifieds[date.formatString("YYYY0MM0DD")]!=undefined);
}
function addModifiedsToPopup(popup,when,format)
{
var date=when.formatString("YYYY0MM0DD");
var force=(store.isDirty() && date==new Date().formatString("YYYY0MM0DD"));
if (force || !config.macros.date.modifieds) config.macros.date.modifieds=indexModifieds();
var indent=String.fromCharCode(160)+String.fromCharCode(160);
var mods = config.macros.date.modifieds[date];
if (mods) {
// if a tiddler was created on this date, don't list it in the 'changed' section
if (config.macros.date.createds && config.macros.date.createds[date]) {
var temp=[];
for(var t=0; t<mods.length; t++)
if (!config.macros.date.createds[date].contains(mods[t]))
temp.push(mods[t]);
mods=temp;
}
mods.sort();
var e=createTiddlyElement(popup,"div",null,null,"changed ("+mods.length+")");
for(var t=0; t<mods.length; t++) {
var link=createTiddlyLink(popup,mods[t],false);
link.appendChild(document.createTextNode(indent+mods[t]));
createTiddlyElement(popup,"br",null,null,null);
}
}
}
//}}}
//{{{
function hasTagged(date,format) // returns true if date is tagging other tiddlers
{
return store.getTaggedTiddlers(date.formatString(format)).length>0;
}
function addTaggedToPopup(popup,when,format)
{
var indent=String.fromCharCode(160)+String.fromCharCode(160);
var tagged=store.getTaggedTiddlers(when.formatString(format));
if (tagged.length) var e=createTiddlyElement(popup,"div",null,null,"tagged ("+tagged.length+")");
for(var t=0; t<tagged.length; t++) {
var link=createTiddlyLink(popup,tagged[t].title,false);
link.appendChild(document.createTextNode(indent+tagged[t].title));
createTiddlyElement(popup,"br",null,null,null);
}
}
//}}}
//{{{
function indexReminders(date,leadtime) // build list of tiddlers with reminders, hash indexed by reminder date
{
var reminders = { };
if(window.findTiddlersWithReminders!=undefined) { // reminder plugin is installed
// DEBUG var starttime=new Date();
var t = findTiddlersWithReminders(date, [0,leadtime], null, null, 1);
for(var i=0; i<t.length; i++) reminders[t[i].matchedDate]=true;
// DEBUG var out="Found "+t.length+" reminders in "+((new Date())-starttime+1)+"ms\n";
// DEBUG out+="startdate: "+date.toLocaleDateString()+"\n"+"leadtime: "+leadtime+" days\n\n";
// DEBUG for(var i=0; i<t.length; i++) { out+=t[i].matchedDate.toLocaleDateString()+" "+t[i].params.title+"\n"; }
// DEBUG alert(out);
}
return reminders;
}
function hasReminders(date) // returns true if date has reminders
{
if (window.reminderCacheForCalendar)
return window.reminderCacheForCalendar[date]; // use calendar cache
if (!config.macros.date.reminders)
config.macros.date.reminders = indexReminders(date,90); // create a 90-day leadtime reminder cache
return (config.macros.date.reminders[date]);
}
function addRemindersToPopup(popup,when,format)
{
if(window.findTiddlersWithReminders==undefined) return; // reminder plugin not installed
var indent = String.fromCharCode(160)+String.fromCharCode(160);
var reminders=findTiddlersWithReminders(when, [0,31],null,null,1);
createTiddlyElement(popup,"div",null,null,"reminders ("+(reminders.length||"none")+")");
for(var t=0; t<reminders.length; t++) {
link = createTiddlyLink(popup,reminders[t].tiddler,false);
var diff=reminders[t].diff;
diff=(diff<1)?"Today":((diff==1)?"Tomorrow":diff+" days");
var txt=(reminders[t].params["title"])?reminders[t].params["title"]:reminders[t].tiddler;
link.appendChild(document.createTextNode(indent+diff+" - "+txt));
createTiddlyElement(popup,"br",null,null,null);
}
if (readOnly) return; // omit "new reminder..." link
var link = createTiddlyLink(popup,indent+"new reminder...",true); createTiddlyElement(popup,"br");
var title = when.formatString(format);
link.title="add a reminder to '"+title+"'";
link.onclick = function() {
// show tiddler editor
story.displayTiddler(null, title, 2, null, null, false, false);
// find body 'textarea'
var c =document.getElementById("tiddler" + title).getElementsByTagName("*");
for (var i=0; i<c.length; i++) if ((c[i].tagName.toLowerCase()=="textarea") && (c[i].getAttribute("edit")=="text")) break;
// append reminder macro to tiddler content
if (i<c.length) {
if (store.tiddlerExists(title)) c[i].value+="\n"; else c[i].value="";
c[i].value += "<<reminder";
c[i].value += " day:"+when.getDate();
c[i].value += " month:"+(when.getMonth()+1);
c[i].value += " year:"+when.getFullYear();
c[i].value += ' title:"Enter a title" >>';
}
};
}
//}}}
/***
|Name|DatePluginConfig|
|Source|http://www.TiddlyTools.com/#DatePluginConfig|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.6.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||
|Overrides||
|Description|formats, background colors and other optional settings for DatePlugin|
***/
// // Default popup content display options (can be overridden by cookies)
//{{{
if (config.options.chkDatePopupHideCreated===undefined)
config.options.chkDatePopupHideCreated=false;
if (config.options.chkDatePopupHideChanged===undefined)
config.options.chkDatePopupHideChanged=false;
if (config.options.chkDatePopupHideTagged===undefined)
config.options.chkDatePopupHideTagged=false;
if (config.options.chkDatePopupHideReminders===undefined)
config.options.chkDatePopupHideReminders=false;
//}}}
// // show Julian date number below regular date
//{{{
if (config.options.chkShowJulianDate===undefined)
config.options.chkShowJulianDate=false;
//}}}
// // fixed-date annual holidays
//{{{
config.macros.date.holidays=[
"01/01", // NewYearsDay,
"07/04", // US Independence Day
"07/24" // Eric's Birthday (hooray!)
];
//}}}
// // weekend map (1=weekend, 0=weekday)
//{{{
config.macros.date.weekend=[ 1,0,0,0,0,0,1 ]; // day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6
//}}}
// // date display/link formats
//{{{
config.macros.date.format="YYYY.0MM.0DD"; // default date display format
config.macros.date.linkformat="YYYY.0MM.0DD"; // 'dated tiddler' link format
//}}}
// // When displaying a calendar (see [[CalendarPlugin]]), you can customize the colors/styles that are applied to the calendar dates by modifying the values and/or functions below:
//{{{
// default calendar colors
config.macros.date.weekendbg="#c0c0c0";
config.macros.date.holidaybg="#ffaace";
config.macros.date.createdbg="#bbeeff";
config.macros.date.modifiedsbg="#bbeeff";
config.macros.date.linkedbg="#babb1e";
config.macros.date.remindersbg="#c0ffee";
// apply calendar styles
function setDateStyle(place,link,weekend) {
// alias variable names for code readability
var date=link.date;
var fmt=link.linkformat;
var linkto=date.formatString(fmt);
var cmd=config.macros.date;
if ((weekend!==undefined?weekend:isWeekend(date))&&(cmd.weekendbg!=""))
{ place.style.background = cmd.weekendbg; }
if (hasModifieds(date)||hasCreateds(date)||hasTagged(date,fmt))
{ link.style.fontStyle="normal"; link.style.fontWeight="bold"; }
if (hasReminders(date))
{ link.style.textDecoration="underline"; }
if (isToday(date))
{ link.style.border="1px solid black"; }
if (isHoliday(date)&&(cmd.holidaybg!=""))
{ place.style.background = cmd.holidaybg; }
if (hasCreateds(date)&&(cmd.createdbg!=""))
{ place.style.background = cmd.createdbg; }
if (hasModifieds(date)&&(cmd.modifiedsbg!=""))
{ place.style.background = cmd.modifiedsbg; }
if ((hasTagged(date,fmt)||store.tiddlerExists(linkto))&&(cmd.linkedbg!=""))
{ place.style.background = cmd.linkedbg; }
if (hasReminders(date)&&(cmd.remindersbg!=""))
{ place.style.background = cmd.remindersbg; }
if (isToday(date)&&(cmd.todaybg!=""))
{ place.style.background = cmd.todaybg; }
if (config.options.chkShowJulianDate) {
var m=[0,31,59,90,120,151,181,212,243,273,304,334];
var d=date.getDate()+m[date.getMonth()];
var y=date.getFullYear();
if (date.getMonth()>1 && (y%4==0 && y%100!=0) || y%400==0) d++; // after February in a leap year
wikify("@@font-size:80%;<br>"+d+"@@",place);
}
}
//}}}
[[Does this taste right to you?]]
[tag[startup]]
/***
|Name|DisableWikiLinksPlugin|
|Source|http://www.TiddlyTools.com/#DisableWikiLinksPlugin|
|Version|1.6.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||
|Overrides|Tiddler.prototype.autoLinkWikiWords, 'wikiLink' formatter|
|Options|##Configuration|
|Description|selectively disable TiddlyWiki's automatic ~WikiWord linking behavior|
This plugin allows you to disable TiddlyWiki's automatic ~WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links. To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[...]]}}}.
!!!!!Usage
<<<
You can block automatic WikiWord linking behavior for any specific tiddler by ''tagging it with<<tag excludeWikiWords>>'' (see configuration below) or, check a plugin option to disable automatic WikiWord links to non-existing tiddler titles, while still linking WikiWords that correspond to existing tiddlers titles or shadow tiddler titles. You can also block specific selected WikiWords from being automatically linked by listing them in [[DisableWikiLinksList]] (see configuration below), separated by whitespace. This tiddler is optional and, when present, causes the listed words to always be excluded, even if automatic linking of other WikiWords is being permitted.
Note: WikiWords contained in default ''shadow'' tiddlers will be automatically linked unless you select an additional checkbox option lets you disable these automatic links as well, though this is not recommended, since it can make it more difficult to access some TiddlyWiki standard default content (such as AdvancedOptions or SideBarTabs)
<<<
!!!!!Configuration
<<<
<<option chkDisableWikiLinks>> Disable ALL automatic WikiWord tiddler links
<<option chkAllowLinksFromShadowTiddlers>> ... except for WikiWords //contained in// shadow tiddlers
<<option chkDisableNonExistingWikiLinks>> Disable automatic WikiWord links for non-existing tiddlers
Disable automatic WikiWord links for words listed in: <<option txtDisableWikiLinksList>>
Disable automatic WikiWord links for tiddlers tagged with: <<option txtDisableWikiLinksTag>>
<<<
!!!!!Revisions
<<<
2008.07.22 [1.6.0] hijack tiddler changed() method to filter disabled wiki words from internal links[] array (so they won't appear in the missing tiddlers list)
2007.06.09 [1.5.0] added configurable txtDisableWikiLinksTag (default value: "excludeWikiWords") to allows selective disabling of automatic WikiWord links for any tiddler tagged with that value.
2006.12.31 [1.4.0] in formatter, test for chkDisableNonExistingWikiLinks
2006.12.09 [1.3.0] in formatter, test for excluded wiki words specified in DisableWikiLinksList
2006.12.09 [1.2.2] fix logic in autoLinkWikiWords() (was allowing links TO shadow tiddlers, even when chkDisableWikiLinks is TRUE).
2006.12.09 [1.2.1] revised logic for handling links in shadow content
2006.12.08 [1.2.0] added hijack of Tiddler.prototype.autoLinkWikiWords so regular (non-bracketed) WikiWords won't be added to the missing list
2006.05.24 [1.1.0] added option to NOT bypass automatic wikiword links when displaying default shadow content (default is to auto-link shadow content)
2006.02.05 [1.0.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.09 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.DisableWikiLinksPlugin= {major: 1, minor: 6, revision: 0, date: new Date(2008,7,22)};
if (config.options.chkDisableNonExistingWikiLinks==undefined) config.options.chkDisableNonExistingWikiLinks= false;
if (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks=false;
if (config.options.txtDisableWikiLinksList==undefined) config.options.txtDisableWikiLinksList="DisableWikiLinksList";
if (config.options.chkAllowLinksFromShadowTiddlers==undefined) config.options.chkAllowLinksFromShadowTiddlers=true;
if (config.options.txtDisableWikiLinksTag==undefined) config.options.txtDisableWikiLinksTag="excludeWikiWords";
// find the formatter for wikiLink and replace handler with 'pass-thru' rendering
initDisableWikiLinksFormatter();
function initDisableWikiLinksFormatter() {
for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);
config.formatters[i].coreHandler=config.formatters[i].handler;
config.formatters[i].handler=function(w) {
// supress any leading "~" (if present)
var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;
var title=w.matchText.substr(skip);
var exists=store.tiddlerExists(title);
var inShadow=w.tiddler && store.isShadowTiddler(w.tiddler.title);
// check for excluded Tiddler
if (w.tiddler && w.tiddler.isTagged(config.options.txtDisableWikiLinksTag))
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// check for specific excluded wiki words
var t=store.getTiddlerText(config.options.txtDisableWikiLinksList);
if (t && t.length && t.indexOf(w.matchText)!=-1)
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// if not disabling links from shadows (default setting)
if (config.options.chkAllowLinksFromShadowTiddlers && inShadow)
return this.coreHandler(w);
// check for non-existing non-shadow tiddler
if (config.options.chkDisableNonExistingWikiLinks && !exists)
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// if not enabled, just do standard WikiWord link formatting
if (!config.options.chkDisableWikiLinks)
return this.coreHandler(w);
// just return text without linking
w.outputText(w.output,w.matchStart+skip,w.nextMatch)
}
}
Tiddler.prototype.coreAutoLinkWikiWords = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function()
{
// if all automatic links are not disabled, just return results from core function
if (!config.options.chkDisableWikiLinks)
return this.coreAutoLinkWikiWords.apply(this,arguments);
return false;
}
Tiddler.prototype.disableWikiLinks_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
this.disableWikiLinks_changed.apply(this,arguments);
// remove excluded wiki words from links array
var t=store.getTiddlerText(config.options.txtDisableWikiLinksList,"").readBracketedList();
if (t.length) for (var i=0; i<t.length; i++)
if (this.links.contains(t[i]))
this.links.splice(this.links.indexOf(t[i]),1);
};
//}}}
[[GettingStarted]]
[[AdvancedOptions]]
[[cookieJar]]
----
<<tiddler ShowPopup with:
DocumentSetup##cookies ~CookieManager "view/modify option cookie settings" tiddlyLinkExisting auto sticky>>
<<tiddler ShowPopup with:
DocumentSetup##tweaker ~TiddlerTweaker "view/modify tiddler values" tiddlyLinkExisting auto sticky>>
----
<<tiddler ShowPopup with:
DocumentSetup##templates templates "list templates" tiddlyLinkExisting auto>>
<<tiddler ShowPopup with:
DocumentSetup##stylesheets stylesheets "list stylesheets" tiddlyLinkExisting auto>>
<<tiddler ShowPopup with:
DocumentSetup##menus menus "list menus" tiddlyLinkExisting auto>>/%
!cookies
{{center{
[[Browser cookies:|CookieManagerPlugin]] {{fine{<<option chkAllowBrowserCookies>>enable <<option chkMonitorBrowserCookies>>monitor}}}
{{fine{
----
{{smallform small{<<cookieManager>>}}}
}}}
!tweaker
{{smallform{
<<tiddlerTweaker>>}}}
!templates
<<matchTags "%0" "<br>" sort:title template>>
!stylesheets
<<matchTags "%0" "<br>" sort:title stylesheet>>
!menus
<<matchTags "%0" "<br>" sort:title menu>>
!end
%/
<<tiddler HideTiddlerTags>><<tiddler HideTiddlerBackground>>
{{center{
<<tiddler [[Does this taste right to you?##image]]>>/%
%/{{big{
"hmmm.... well, now that you mention it... it //is// a bit lumpy.}}}
{{medium italic{
@@font-family:Trebuchet MS;''~LumpyMilk'' offers selected "musings and mumbles" (original writings and collected clippings from other sources) ranging from the ''bizarre'' to the ''beautiful'' mixed with a sense of ''whimsy'' and ''wonderment'' at how genuinely remarkable the human experience really is...
...counterbalanced by ''things that make you go, "hmmm"'': the vexingly ''consistent inconsistencies'' of life in the modern world that seem to ''defy common sense'' yet add those surprisingly satisfying twists and turns that keeps things interesting!@@}}}
//As you travel through life, may you://
{{big{Be Well. Be Happy. Be Kind.}}}@@/%
HIDDEN SECTION WITH BASE64-ENCODED IMAGE DATA
!image
[>img[data://image/gif;base64,R0lGODlhZACMALMAAAAAAAgICBAQECAgIDU1NVZWVn9/f6SkpP8A/729vc7Ozt7e3ufn5+/v7/f39////yH5BAEAAAgALAAAAABkAIwAAAT+EMlJq7046827/+BmAGRZGmGqriJBGEfzzPSTGIQgoGzvb4eCISGrGY0KQ2FQ+Dl/hqHjSK0yDoTCIfHschKHMKNKLt+EB6+aEg5Py3DyVchbP8GKuB7uOCibdixRCgpve4dkN1mBITgGY4iRcEkujB1CeZKacAsEAJYZWQubpHEKOqAVWqWscVgCqUJFrbRkOIxJmbW7VQsFBGpBB4a8xUdYaU5+usbNRgwGA3UqaM7WVQcA0yC/B9ffRwmVIS+zpAphUb8uLgW/OgJZMAejxZ2wHzubDehRYQkMiJHhB2YJCQFoILEqgI+Dtkj9YCRIoEAhjQUKJmrcSEhBvRr+fgqQWFVqhENveq5EkQhmSwMHijwBiMeups0BM7PQqzGChLQEAvcQGKBBQII4C4KgaZlgQYM5A14cKBQJJg4dJB84EqmN2R4AgCwIQNkLzKB+BwIm/WXAK6sG0RCOUVAgj7gdRw8p+GQBANkj0KJMTJfJDwy3vCi1pYtyAQ4CefVoqfCQSoM2Gf0VMTwM3IwkBSaGpqFgaGQ4DPhKcIcNhkoYb/xM9Qz4HwwaDnAUCEolLAIAQZMYWHBjyEXBtKvARUfAXLYCeupAPhZaOFAass0lN4LFcXOQ0uKEBXCMACEhxPyc3n4kN3QhRjoZKJNaAgCvWFR+nIGe/STICgz+YJENfpGRg31GuNDJXw80QACD/mFDwFrH3EdFNhNAR4MBAqCzXm4GaEdbAlxNeOGDuxnhAADrPVDfBGQdYFRaR8DHHjQCmEAChDbgNMARAzAYoG+RBdnUEdEM+I1jOepYQota+RRZNtxJYwFGHCogYidQOnMZTk6aYNQRe5VQXVTYubONBPFEw9uDyYkTZpgCKMmVji84kswFODBgXjgEKOlMT3i6844JBByxwJxmcoBDENfxx2Mz2ZTwApRzkJCoEYSWIMAAYPqGQTTyaEGXoJSS0FaDHlZEpkib4uZkVDn4qFooYMk0H0hDgToUO10eEkQ96GjJG3aVIWsCHbX+luCBCTQ0ACajYIkYRx9kHVtFEhatGCYTTd5aVAmQJECtjiEegu0MubFjqlNlOGbOndR+UAJKZYI1BGI2wLBfFevOgIUWcuqYEBK7zmAutUTZu+NnJGhbA7b80gDGLAx4VMjCmoLhSQH/hpFUGE0iFC4JKagqcLIK/xPcbMptAfBaaDy1AANbSjVGpQC4oGPKYPHH4kWG6cKPIUl1efEuMdRw8sniOhR0JwBAcllkly1lCDr/CjzpJmCAhOdQzjoMHV0aPrDTZTJpQxF3EPZRsSZJTKwjqNOCoOpRq7q4UjQmuKQizDRc0XUpddcgE605oKz3fd4U4culD9AFABP+fXO3HjqobpL4hgf16rjeQf41CJkAbcuSU2B0rknYNaQWZsptAEyatSCl83ewmshshJgvRL1B0FeU0QDumidfC1xUgCmAVhjqvRktWhoBO/UJ1wDmfHAJr0HCBkhMyhVzH3IZYj3l4cCB9s4yHCsO8AaG+Hpcj4TKD/wCQva+k9J/DVdjhf3io7IrNIQDBCCGY0pxvm0RThKcK4NPZvAiBELof4gIIBmKJYkGLE2CJKCB9/oSFGi4zgqwmUQYkHeEy3QGDk2az146EB4qfHAPIDohu5YRBxcejgol+NGaMFA1MoQBEVHQYQ3QsZMWmqVpewjXARrmkDJg64ecSpf+JKimL3VIRBLTGp0I4nCD8mGBdwP5WM9oEcYDZqBAcYDGVKxVmq8Zr09Ryt4m6DVCChRxD2jZgkawED66vTAbCKFfGfgoNboNBiC52ERAsAODqCixCjKJRzyG9yNW+EKL53CD2j5VPjKEcREaCFopfDGWUjCgG4ZIACk1EcYdvVGVpFgJFl0RFQgFaAAsrAKexEgZOHpuLFR5XTx44wA/BSoSiMoCMIjIsqqMgEZ79Es/1PSgZbgAEYs6QTaG+JuR+I9EdoTDCBDiq1/5pGc46GT90EXMCZjJc/O5QTCrwLHLReUX35rJPgk0pwsEURMOKIAMxFHK9rSNTr/yBBP+ZkI/nl0uXAadoCRu84D1NXRifDxIuOJBK3iuEQ5k84lBhActiPyJEEGKRKd88qtP4eRTmtxBjuwYTjGBKaMhjISa/jCTj74SogOARyZ14COJaotjCPlZX56ECBm1o23ScF1SankuOpkTk0EklEiAakw9OO8gYiKYljASEqh1tau86akJmkrWWLnCSb/g6lvn1CRQ6QhqiAlprnpGVvIIJam+iopb9+qpkrljJDiwFL0gxIAwRvZT9SwnufSQjV6llLGMQohBpHGnLPhopSflSRgnagKDti1tZfBrUhv3Vpv6VQez+iw8seCpaT1viTMJU9suQC952sJToO1Z24b+oslZZbVw1GKGYDXVk4yGq3zT7apf5zqUeUyhUnp8qJNQsr6nRfadwsuCCfSoIsa2EbeXEwKUhMEdJ6kXfyMQb1QMRk1PmQG5OfoUbS8XRHk80AgexOAMxNuzBIBpQo1bLHpvud2v9cSmDPGZgCM7GtS0BJv19ZRM7huP4IpUU5bCyS0BSoIujVi56FqZiVTEALP4gwjKaWMm+ejbJg0YIbfEqU8QUzIC48liK6EDHfyxhRPOtGcl+utbpwnU816uRVM2R0Y04hF46WF9TkKIJyQ8J9oGuZY1FCFfpwVbVlgUsyal051MNpJK3TJ0KNbGLBhlkBjSAswi9jFf6fX+2NamciR3spWGwkVb9T4ITOnkbBA1pde7nWt4ebbUens2kiYZxMpl3aiIaSrnSjsJ05bqyeI4fVM25whwff3oMcCEk8btN0xaMNiLNbUBkYTqvQSu9Ugv5wmfjUSRsQtCgH2UI93OFXCSHYlEOwBf5AK402MbbM8Q8tE+wGCd+72peEt8kFoO2439DW5zhQs1zLK4ccPxCBmSwmQf7TfA42axpxgi5T7a88QDBjCZjU22CTGxDQj/wxB84ZOklvjWJr4vojiEp2e5ldyaIvdiFTuTpBbIxkNtw8UC1PGc5OiUtHarrYNLZQ6o3OPlZgi5a/lZHzVlKh9uCiHwcOH+pgo3u8vScD4OUqliz9XeGRfTXHNUFwZcIR2YwRJai4zny0F73+0eq8O0QSifGRvbGl4zTgqAM0L84x9qa/icpDHikAZvmCFA66TBcrIHnzzAUNsu92TTEnQ4/FwSXzuxaUrFZ62dwegdMc1h7o3B0OMKOQh4mRms27FQOgWIJzC/JX/rHDwN5tpYQCybDXpE0UvlM/VZVFRQ7q/vYPB3W3VKh62pxozZ2WHNvKXyfjkWbPuzPuO33OFb61b/lda0hbi14clVlXPlpyuwb8QzLnzkkm3dQcx7tUM3rcDH174X9jemfUx5dpS52REWE1NtWubqt9vKfS1bD4wsI+n+93lW6J9JgIEnuiB2n8HhwlpRJXc/YGI98V6bxyi3hXci1n+hQ2awZ2Ls9E5PcFYD2Db5Z2olt3049U8lonsmF2a4lVRdgFVjVktxkUnUgltkA3FC8ID9Rmpy906F9wM7xmxpNVhwFlowBi4qpXvbVW4z0SnT5gUpxmlGpl6jdXcmRi1f93Vhhng7MGbEtgaLAyoiQW7wVmw60Di491cQuIOlp3Q+EQgE9in5FX/bdoaKl1yzkl1QmFkl2HFGBxZndVvi9negBWdi1m/KJ34FyGlRRWeN5U8m53FBKIF5Z4J4clbqlgpG52iZR3wX1TN/B2cL6H+Mcl9nlQr2wYXb2gaBlchc+JaBvgWAGRZlYOGJGWJkfSVsa3d38MWCEvVQYygN+4eErOhHzWYmYweLZHhiRxeBf+WFJ6Ziu0gBdchqMscQYxiMQliJuFZct5eMFUBb5HdRceiGUmZsOGiN6YYoJKV/s6WBTuhr4iZ/4GgBKkiGtPKOoihcF9aFcriO9rRYXdhOS/BZHOhwEoWEiAiI9jh3d+MrmuQCNFErs9Umgec89qg3DMhXuYI3tRJ58bCPp/aQQNNVAXiCl6aRPQCAuWhtF0dYIPkE3FhxJ2kHe7iSLpmMEQAAADs=]]
!end
%/
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div macro='tiddler QuickEditToolbar with: show'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<span macro='resizeEditor'></span>
<!--}}}-->
<<tiddler HideTiddlerTags>>/%
Description: This Crazy Language
%/@@display:block;width:80%;margin:0 auto;{{medium{
{{center{
{{big{English is Tough Stuff}}}
(author unknown)}}}
>Multi-national personnel at North Atlantic Treaty Organization headquarters near Paris found English to be an easy language ... until they tried to pronounce it. To help them discard an array of accents, the verses below were devised. After trying them, a Frenchman said he'd prefer six months at hard labor to reading six lines aloud. Try them yourself - it's a pain!
{{center{
Dearest creature in creation,
Study English pronunciation.
I will teach you in my verse
Sounds like corpse, corps, horse, and worse.
I will keep you, Suzy, busy,
Make your head with heat grow dizzy.
Tear in eye, your dress will tear.
So shall I! Oh hear my prayer.
Just compare heart, beard, and heard,
Dies and diet, lord and word,
Sword and sward, retain and Britain.
(Mind the latter, how it's written.)
Now I surely will not plague you
With such words as plaque and ague.
But be careful how you speak:
Say break and steak, but bleak and streak;
Cloven, oven, how and low,
Script, receipt, show, poem, and toe.
Hear me say, devoid of trickery,
Daughter, laughter, and Terpsichore,
Typhoid, measles, topsails, aisles,
Exiles, similes, and reviles;
Scholar, vicar, and cigar,
Solar, mica, war and far;
One, anemone, Balmoral,
Kitchen, lichen, laundry, laurel;
Gertrude, German, wind and mind,
Scene, Melpomene, mankind.
Billet does not rhyme with ballet,
Bouquet, wallet, mallet, chalet.
Blood and flood are not like food,
Nor is mould like should and would.
Viscous, viscount, load and broad,
Toward, to forward, to reward.
And your pronunciation's OK
When you correctly say croquet,
Rounded, wounded, grieve and sieve,
Friend and fiend, alive and live.
Ivy, privy, famous; clamour
And enamour rhyme with hammer.
River, rival, tomb, bomb, comb,
Doll and roll and some and home.
Stranger does not rhyme with anger,
Neither does devour with clangour.
Souls but foul, haunt but aunt,
Font, front, wont, want, grand, and grant,
Shoes, goes, does. Now first say finger,
And then singer, ginger, linger,
Real, zeal, mauve, gauze, gouge and gauge,
Marriage, foliage, mirage, and age.
Query does not rhyme with very,
Nor does fury sound like bury.
Dost, lost, post and doth, cloth, loth.
Job, nob, bosom, transom, oath.
Though the differences seem little,
We say actual but victual.
Refer does not rhyme with deafer.
Foeffer does, and zephyr, heifer.
Mint, pint, senate and sedate;
Dull, bull, and George ate late.
Scenic, Arabic, Pacific,
Science, conscience, scientific.
Liberty, library, heave and heaven,
Rachel, ache, moustache, eleven.
We say hallowed, but allowed,
People, leopard, towed, but vowed.
Mark the differences, moreover,
Between mover, cover, clover;
Leeches, breeches, wise, precise,
Chalice, but police and lice;
Camel, constable, unstable,
Principle, disciple, label.
Petal, panel, and canal,
Wait, surprise, plait, promise, pal.
Worm and storm, chaise, chaos, chair,
Senator, spectator, mayor.
Tour, but our and succour, four.
Gas, alas, and Arkansas.
Sea, idea, Korea, area,
Psalm, Maria, but malaria.
Youth, south, southern, cleanse and clean.
Doctrine, turpentine, marine.
Compare alien with Italian,
Dandelion and battalion.
Sally with ally, yea, ye,
Eye, I, ay, aye, whey, and key.
Say aver, but ever, fever,
Neither, leisure, skein, deceiver.
Heron, granary, canary.
Crevice and device and aerie.
Face, but preface, not efface.
Phlegm, phlegmatic, ass, glass, bass.
Large, but target, gin, give, verging,
Ought, out, joust and scour, scourging.
Ear, but earn and wear and tear
Do not rhyme with here but ere.
Seven is right, but so is even,
Hyphen, roughen, nephew Stephen,
Monkey, donkey, Turk and jerk,
Ask, grasp, wasp, and cork and work.
Pronunciation -- think of Psyche!
Is a paling stout and spikey?
Won't it make you lose your wits,
Writing groats and saying grits?
It's a dark abyss or tunnel:
Strewn with stones, stowed, solace, gunwale,
Islington and Isle of Wight,
Housewife, verdict and indict.
Finally, which rhymes with enough --
Though, through, plough, or dough, or cough?
Hiccough has the sound of cup.
My advice is to give up!!!
}}}}}}@@
/%
URL: http://www.flickr.com/groups/hdr/pool/show/
Description: HDR slideshow from flickr.com
Author: various
%/
<<tiddler AutoRefresh with: force>><<tiddler HideTiddlerBackground>><<tiddler HideTiddlerTags>>{{transparent smallform{<<faqViewer faq 'viewer scrollbars'>>}}}
/***
|Name|FAQViewerPlugin|
|Source|http://www.TiddlyTools.com/#FAQViewerPlugin|
|Version|1.4.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|select and display FAQ tiddlers from a droplist, sorted by date|
!!!!!Usage
<<<
{{{<<faqViewer startwith:TiddlerName tagname classname sortby dateformat>>}}}
where:
*''startwith:TiddlerName'' (optional)<br>
*''tagname'' (optional)<br>specifies the set of tiddlers to include in the FAQ list (default='faq')
*''classname'' (optional)<br>specifies a CSS class to be applied surrounding the FAQ tiddler content
*''sortby'' (optional)<br>specifies the name of a tiddler field to sort by. Use "+" or "-" as a prefix on the fieldname to indicate ascending or descending order, respectively (default='-modified'). You can also use the special keyword, ''Description'', to sort alphabetically based on the value of a slice named "Description", that can be defined in each FAQ tiddler. Note: if a particular FAQ tiddler has no description slice, the title of the tiddler is used as a fallback.
*''dateformat'' (optional)<br>specifies the formatting for dates displayed in the list. Use " " (a single space) to suppress the date display.
examples:
{{{<<faqViewer>>}}}
{{smallform small{<<faqViewer>>}}}
{{{<<faqViewer package outline +title " ">>}}}
{{smallform small{<<faqViewer package outline +title " ">>}}}
<<<
!!!!!Revisions
<<<
2008.10.21 [1.4.2] removed animation (was interfering with "overflow:scroll" CSS)
2008.09.30 [1.4.1] corrected filter by tag handling broken in 1.4.0
2008.09.29 [1.4.0] added optional "startwith:TiddlerName" param
2008.09.24 [1.3.1] added animation when opening/closing faq content panel
2008.09.21 [1.3.0] sort by "description" slice values. also added "previous" and "next" buttons for sequential viewing of FAQ articles
2008.09.20 [1.2.0] optional 'sortby' and 'dateformat' params
2008.01.20 [1.1.0] support for alternative 'target' tag instead of "faq" (default)
2007.10.15 [1.0.0] converted to true plugin
2007.02.01 [0.0.0] inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.FAQViewerPlugin={major: 1, minor: 4, revision: 1, date: new Date(2008,9,30)};
config.shadowTiddlers.FAQViewer="{{smallform{<<faqViewer>>}}}";
config.macros.faqViewer= {
dateFormat:"YYYY.0MM.0DD 0hh:0mm - ",
startparam: "startwith:",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
// create form
if (params[0]&¶ms[0].substr(0,this.startparam.length)==this.startparam)
{ var startwith=params[0].substr(this.startparam.length); params.shift(); }
var console=createTiddlyElement(place,"span");
console.innerHTML=this.html.replace(/%classname%/,params[1]||"");
this.go(console.getElementsByTagName("form")[0],startwith, params[0],params[2],params[3]);
},
go: function(f,startwith,targetType,sortby,dateformat) {
var targetType=targetType||"faq";
var sortby=sortby||"-modified";
var dateformat=dateformat||this.dateFormat;
var datefield=sortby.indexOf('created')!=-1?'created':'modified';
f.targetType.value=targetType;
f.sortBy.value=sortby;
f.dateFmt.value=dateformat;
var lists=f.getElementsByTagName("select"); if (!lists.length) return;
var FAQList=lists[0]; var taglist=lists[1];
while (FAQList.options[0]) FAQList.options[0]=null; // empty FAQList
if (f.search.value!=f.search.defaultValue) var find=f.search.value;
var tiddlers=store.getTaggedTiddlers(targetType,"modified").reverse();
if (tiddlers && sortby) {
if (sortby.indexOf('escription')==-1) // sort by tiddler field
tiddlers=store.sortTiddlers(tiddlers,sortby);
else
tiddlers.sort(function(a,b){ // sort by description slice (or title, if no slice)
var da=store.getTiddlerSlice(a.title,"Description")||a.title;
var db=store.getTiddlerSlice(b.title,"Description")||b.title;
return da==db?0:(da>db?+1:-1);
});
}
var matchcount=0; var tags=[]; var selectedIndex=0;
FAQList.options[0]=new Option("select an item...","",false,false);
for (var i=0; i<tiddlers.length; i++) {
for (var t=0; t<tiddlers[i].tags.length; t++)
tags.pushUnique(tiddlers[i].tags[t]); // collect other tags
if (find && find.length && tiddlers[i].text.indexOf(find)==-1) continue;
if (taglist.value && taglist.value.length && !tiddlers[i].tags.contains(taglist.value)) continue;
matchcount++;
var d=store.getTiddlerSlice(tiddlers[i].title,"Description")||tiddlers[i].title;
d=tiddlers[i][datefield].formatString(dateformat)+d;
FAQList.options[FAQList.options.length]=new Option(d,tiddlers[i].title,false,false);
if (tiddlers[i].title==startwith) selectedIndex=i+1;
}
FAQList.options[0].text="select an item... ["+tiddlers.length+" item"+(tiddlers.length!=1?"s":"");
if (find && find.length || taglist.value.length)
FAQList.options[0].text+=", "+matchcount+" match"+(matchcount!=1?"es":"");
FAQList.options[0].text+="]";
FAQList.selectedIndex=selectedIndex;
if (selectedIndex) config.macros.faqViewer.show(f,startwith);
if (!taglist.options.length) { // only load tag list the first time, since it doesn't change
while (taglist.options[0]) taglist.options[0]=null; // empty taglist
taglist.options[0]=new Option("filter by tag...","",false,false);
var tagcount=0;
for (var t=0; t<tags.length; t++) {
if (tags[t].toLowerCase()==targetType) continue;
if (tags[t].indexOf("exclude")!=-1) continue;
taglist.options[taglist.options.length]
=new Option(tags[t],tags[t],false,false);
tagcount++;
}
if (!tagcount) taglist.options[taglist.options.length]
=new Option("no category tags found","",false,false);
}
},
show: function(f,v) {
var fmt=this.faqlayout;
if (store.getTaggedTiddlers(v).length) fmt=this.packagelayout;
var target=f.getElementsByTagName("div")[0];
removeChildren(target);
wikify(fmt.format([v]),target);
target.style.display="block";
f.prev.parentNode.style.display="block";
f.next.focus();
f.done.disabled=!v.length;
},
faqlayout:
"{{toolbar floatright fine{//now viewing: //[[%0]] }}}<<tiddler [[%0]]>>",
packagelayout:
"{{toolbar floatright fine{//now viewing: //[[%0]] }}}\n"
+"{{floatright borderleft fine{<<tagging [[%0]]>>}}}<<tiddler [[%0]]>>{{clear block{}}}",
html:
"<form onsubmit='return false;' style='display:inline;margin:0;padding:0;white-space:nowrap;'><!-- \
--><input type='hidden' name='targetType' value='faq'><!-- \
--><input type='hidden' name='sortBy' value='-modified'><!-- \
--><input type='hidden' name='dateFmt' value='YYYY.0MM.0DD 0hh:0mm - '><!-- \
--><select name='list' size=1 style='width:50%' \
onchange='if (!this.value.length) this.form.done.onclick(); \
else config.macros.faqViewer.show(this.form,this.value);'><!-- \
--></select><!-- \
--><select name='taglist' size=1 style='width:12%' \
title='list only items that have a specific category tag' \
onchange='var f=this.form; f.done.onclick(); \
config.macros.faqViewer.go(f,\"\",f.targetType.value,f.sortBy.value,f.dateFmt.value)'><!-- \
--></select><!-- \
--><input type='text' name='search' value='enter search text...' style='width:20%' \
title='list only items that contain the search text (use blank to match all)' \
onfocus='this.select()' \
onkeyup=' if (event.keyCode==13) this.form.find.onclick(); \
if (!this.value.length) {this.value=this.defaultValue; this.select(); this.form.find.onclick();}'><!-- \
--><input type='button' name='find' value='find' style='width:6%' \
title='list only items that contain the search text ' \
onclick='var f=this.form; f.done.onclick(); \
config.macros.faqViewer.go(f,\"\",f.targetType.value,f.sortBy.value,f.dateFmt.value)'><!-- \
--><input type='button' name='reset' value='reset' style='width:6%' \
title='reset FAQViewer to default ' \
onclick='var f=this.form; f.done.onclick(); \
f.search.value=f.search.defaultValue; f.taglist.selectedIndex=0; \
config.macros.faqViewer.go(f,\"\",f.targetType.value,f.sortBy.value,f.dateFmt.value)'><!-- \
--><input type='button' name='done' value='done' disabled style='width:6%' \
title='hide current item display' \
onclick='var target=this.form.getElementsByTagName(\"div\")[0]; \
target.style.display=\"none\"; removeChildren(target); \
this.form.prev.parentNode.style.display=\"none\"; \
this.form.list.selectedIndex=0; this.disabled=true;'><!-- \
--><div class=\"%classname%\" style=\"display:none;white-space:normal;\"></div><!-- \
--><span style='text-align:right;display:none;overflow:auto;'><!-- \
--><input type='button' name='prev' value='◄ prev' style='float:left;font-size:80%;' \
title='view previous item' \
onclick='var f=this.form; var i=f.list.selectedIndex-1; \
f.list.selectedIndex=i<0?f.list.length-1:i; f.list.onchange();'><!-- \
--><input type='button' name='next' value='next ►' style='float:right;font-size:80%;' \
title='view next item' \
onclick='var f=this.form; var i=f.list.selectedIndex+1; \
f.list.selectedIndex=i>f.list.length-1?0:i; f.list.onchange();'><!-- \
--></span><!-- \
--></form>\
"
}
//}}}
/***
|FileDropPlugin|h
|author : BradleyMeck|
|version : 0.1.1|
|date : Nov 13 2006|
|usage : drag a file onto the TW to have it be made into a tiddler|
|browser(s) supported : Mozilla|
Note: this version has been 'tweaked' by Eric Shulman (http://www.TiddlyTools.com) to add suspend/resume notification handling to improve performance when multiple files are dropped at once.
!Trouble Shooting
*If the plugin does not seem to work, open up the page "about:config" (just type it in the address bar) and make sure @@color(blue):signed.applets.codebase_principal_support@@ is set to @@color(blue):true@@
!Revisions
*Multiple File Dropping API updated, to end all capturing events after yours return a value that makes if(myFunctionsReturnValue) evaluate to true
*Added support for multiple file drop handlers
**Use the config.macros.fileDrop.addEventListener(@@color(green):String Flavor@@, @@color(green):Function handler(nsiFile){}@@, @@color(green):Boolean addToFront@@) function
***Standard Flavor is "application/x-moz-file"
***addToFront gives your handler priority over all others at time of add
*Old plugin would disallow drops of text vetween applications because it didn't check if the transfer was a file.
!Example Handler
*Adds simple file import control, add this to a tiddler tagged {{{systemConfig}}} to make file dropping work
{{{
config.macros.fileDrop.addEventListener("application/x-moz-file",function(nsiFile)
{
if(
confirm("You have dropped the file \""+nsiFile.path+"\" onto the page, it will be imported as a tiddler. Is that ok?")
)
{
var newDate = new Date();
var title = prompt("what would you like to name the tiddler?");
store.saveTiddler(title,title,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);
}
return true;
})
}}}
!Example Handler without popups and opening the tiddler on load
*Adds simple file import control, add this to a tiddler tagged {{{systemConfig}}} to make file dropping work
{{{
config.macros.fileDrop.addEventListener("application/x-moz-file",function(nsiFile)
{
var newDate = new Date();
store.saveTiddler(nsiFile.path,nsiFile.path,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);
story.displayTiddler(null,nsiFile.path)
return true;
})
}}}
!Code
***/
//{{{
config.macros.fileDrop = {version : {major : 0, minor : 0, revision: 1}};
config.macros.fileDrop.customDropHandlers = [];
config.macros.fileDrop.dragDropHandler = function(evt) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
// Load in the native DragService manager from the browser.
var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
// Load in the currently-executing Drag/drop session.
var dragSession = dragService.getCurrentSession();
// Create an instance of an nsITransferable object using reflection.
var transferObject = Components.classes["@mozilla.org/widget/transferable;1"].createInstance();
// Bind the object explicitly to the nsITransferable interface. We need to do this to ensure that
// methods and properties are present and work as expected later on.
transferObject = transferObject.QueryInterface(Components.interfaces.nsITransferable);
// I've chosen to add only the x-moz-file MIME type. Any type can be added, and the data for that format
// will be retrieved from the Drag/drop service.
transferObject.addDataFlavor("application/x-moz-file");
// Get the number of items currently being dropped in this drag/drop operation.
var numItems = dragSession.numDropItems;
// ELS 2007.12.03: performance improvement when dropping multiple files
if (numItems>1) {
clearMessage();
displayMessage("Reading "+numItems+" files...");
store.suspendNotifications();
}
for (var i = 0; i < numItems; i++)
{
// Get the data for the given drag item from the drag session into our prepared
// Transfer object.
dragSession.getData(transferObject, i);
// We need to pass in Javascript 'Object's to any XPConnect method which
// requires OUT parameters. The out value will then be saved as a new
// property called Object.value.
var dataObj = {};
var dropSizeObj = {};
for(var ind = 0; ind < config.macros.fileDrop.customDropHandlers.length; ind++)
{
var item = config.macros.fileDrop.customDropHandlers[ind];
if(dragSession.isDataFlavorSupported(item.flavor))
{
transferObject.getTransferData(item.flavor, dataObj, dropSizeObj);
var droppedFile = dataObj.value.QueryInterface(Components.interfaces.nsIFile);
// Display all of the returned parameters with an Alert dialog.
var result = item.handler.call(item,droppedFile);
// Since the event is handled, prevent it from going to a higher-level event handler.
evt.stopPropagation();
evt.preventDefault();
if(result){break;}
}
}
}
// ELS 2007.12.03: performance improvement and feedback after dropping multiple files
if (numItems>1) {
store.resumeNotifications();
store.notifyAll();
displayMessage(numItems+" files have been processed");
}
}
if(!window.event)
{
// Register the event handler, and set the 'capture' flag to true so we get this event
// before it bubbles up through the browser.
window.addEventListener("dragdrop", config.macros.fileDrop.dragDropHandler , true);
}
config.macros.fileDrop.addEventListener = function(paramflavor,func,inFront)
{
var obj = {};
obj.flavor = paramflavor;
obj.handler = func;
if(!inFront)
{config.macros.fileDrop.customDropHandlers.push(obj);}
else{config.macros.fileDrop.customDropHandlers.shift(obj);}
}
//}}}
/***
|Name|FileDropPluginConfig|
|Source|http://www.TiddlyTools.com/#FileDropPluginConfig|
|Version|1.5.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|FileDropPlugin, AttachFilePlugin|
|Overrides||
|Options|##Configuration|
|Description|Adds drag-and-drop handlers for creating binary attachments or directory lists|
__TiddlyTools FileDrop+AttachFile extended handler:__
* use just filename instead of whole path as tiddler title
* check for existing tiddler and prompt for new name
* handle folder drops (drops each file or creates a file list in a tiddler)
* use AttachFilePlugin if MIME type is not text/plain
* autotag created tiddlers (e.g., "temporary", "dropped", etc.)
* option to suppress automatic display of newly created tiddlers
* suspend/resume notifications when handling multiple files (performance improvement)
!!!!!Configuration
<<<
<<option chkFileDropTrimFilename>> Omit file extensions from tiddler titles when creating new tiddlers
{{{usage: <<option chkFileDropTrimFilename>> }}}
<<option chkFileDropDisplay>> Automatically display newly created tiddlers
{{{usage: <<option chkFileDropDisplay>> }}}
Tag newly created tiddlers with: <<option txtFileDropTags>>
{{{usage: <<option txtFileDropTags>>}}}
__FileDrop+AttachFile configuration options:__
<<option chkFileDropAttachLocalLink>> Include reference to local path/filename
{{{usage: <<option chkFileDropAttachLocalLink>> }}}
<<option chkFileDropAttachEncodeData>> Include binary file data as encoded "base64" text
{{{usage: <<option chkFileDropAttachEncodeData>> }}}
...only if file is smaller than: <<option txtFileDropAttachDataLimit>> bytes
{{{usage: <<option txtFileDropAttachDataLimit>>}}}
See [[FileDropPlugin]] for more documentation on handler implementation specifics, including sample code for default drop handlers.
<<<
!!!!!Revisions
<<<
2008.08.11 [1.5.1] added chkFileDropAttachLocalLink option to allow suppression of local path/file link
2007.01.01 [0.9.9] initial release with extensions for AttachFilePlugin
<<<
!!!!!Code
***/
//{{{
if (config.options.chkFileDropAttachEncodeData==undefined)
config.options.chkFileDropAttachEncodeData=true;
if (config.options.chkFileDropAttachLocalLink==undefined)
config.options.chkFileDropAttachLocalLink=true;
if (config.options.txtFileDropAttachDataLimit==undefined)
config.options.txtFileDropAttachDataLimit=32768;
if (config.options.txtFileDropTags==undefined)
config.options.txtFileDropTags="";
if (config.options.chkFileDropDisplay==undefined)
config.options.chkFileDropDisplay=true;
if (config.options.chkFileDropTrimFilename==undefined)
config.options.chkFileDropTrimFilename=false;
config.macros.fileDrop.addEventListener("application/x-moz-file",function(nsiFile)
{
var header="Index of %0\n^^(as of %1)^^\n|!filename| !size | !modified |\n";
var item="|[[%0|%1]]| %2|%3|\n";
var footer="Total of %0 bytes in %1 files\n";
var now=new Date();
var files=[nsiFile];
if (nsiFile.isDirectory()) {
var folder=nsiFile.directoryEntries;
var files=[];
while (folder.hasMoreElements()) {
var f=folder.getNext().QueryInterface(Components.interfaces.nsILocalFile);
if (f instanceof Components.interfaces.nsILocalFile && !f.isDirectory()) files.push(f);
}
var msg=nsiFile.path.replace(/\\/g,"/")+"\n\n";
msg+="contains "+files.length+" files... ";
msg+="select OK to attach all files or CANCEL to create a list...";
if (!confirm(msg)) { // create a list in a tiddler
var title=nsiFile.leafName; // tiddler name is last directory name in path
while (title && title.length && store.tiddlerExists(title)) {
if (confirm(config.messages.overwriteWarning.format([title]))) break; // use existing title
title=prompt("Please enter a different tiddler title for this file",nsiFile.path.replace(/\\/g,"/"));
}
if (!title || !title.length) return true; // aborted by user... we're done!
var text=header.format([nsiFile.path.replace(/\\/g,"/"),now.toLocaleString()]);
var total=0;
for (var i=0; i<files.length; i++) { var f=files[i];
var name=f.leafName;
if (config.options.chkFileDropTrimFilename)
{ var p=name.split("."); if (p.length>1) p.pop(); name=p.join("."); }
var path="file:///"+f.path.replace(/\\/g,"/");
var size=f.fileSize; total+=size;
var when=new Date(f.lastModifiedTime).formatString("YYYY.0MM.0DD 0hh:0mm:0ss");
text+=item.format([name,path,size,when]);
}
text+=footer.format([total,files.length]);
var newtags=config.options.txtFileDropTags?config.options.txtFileDropTags.readBracketedList():[];
store.saveTiddler(null,title,text,config.options.txtUserName,now,newtags);
if (config.options.chkFileDropDisplay) story.displayTiddler(null,title);
return true;
}
}
if (files.length>1) store.suspendNotifications();
for (i=0; i<files.length; i++) {
var file=files[i];
if (file.isDirectory()) continue; // skip over nested directories
var type="text/plain";
var title=file.leafName; // tiddler name is file name
if (config.options.chkFileDropTrimFilename)
{ var p=title.split("."); if (p.length>1) p.pop(); title=p.join("."); }
var path=file.path;
var size=file.fileSize;
while (title && title.length && store.tiddlerExists(title)) {
if (confirm(config.messages.overwriteWarning.format([title]))) break; // use existing title
title=prompt("Please enter a different tiddler title for this file",path.replace(/\\/g,"/"));
}
if (!title || !title.length) continue; // cancelled by user... skip this file
if (config.macros.attach) {
type=config.macros.attach.getMIMEType(file.leafName,"");
if (!type.length)
type=prompt("Unrecognized file type. Please enter a MIME type for this file","text/plain");
if (!type||!type.length) continue; // cancelled by user... skip this file
}
var newtags=config.options.txtFileDropTags?config.options.txtFileDropTags.readBracketedList():[];
if (type=="text/plain")
store.saveTiddler(null,title,loadFile(path),config.options.txtUserName,now,newtags);
else {
// only encode data if enabled and file is smaller than limit. Default is 32768 (32K) bytes.
var embed=config.options.chkFileDropAttachEncodeData
&& file.fileSize<config.options.txtFileDropAttachDataLimit;
newtags.push("attachment"); newtags.push("excludeMissing");
var localfile="";
if (config.options.chkFileDropAttachLocalLink) {
// if file is in current document folder,
// remove path prefix and use relative reference
var localfile=path;
var h=document.location.href;
folder=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
if (localfile.substr(0,folder.length)==folder)
localfile='./'+localfile.substr(folder.length);
}
config.macros.attach.createAttachmentTiddler(path,
now.formatString(config.macros.timeline.dateFormat),
"attached by FileDropPlugin", newtags,
title, embed, config.options.chkFileDropAttachLocalLink, false,
localfile, "", type,!config.options.chkFileDropDisplay);
}
if (config.options.chkFileDropDisplay) story.displayTiddler(null,title);
}
if (files.length>1) { store.resumeNotifications(); store.notifyAll(); }
if (window.FFDEBUG) console.log(new Date()-now);
return true;
})
//}}}
/%
|Name|FoldOtherTiddlers|
|Source|http://www.TiddlyTools.com/#FoldOtherTiddlers|
|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||
|Overrides||
|Description|fold all other tiddlers when a tiddler is viewed - equivalent to pressing "focus" toolbar command|
Usage: <<tiddler FoldOtherTiddlers>>
%/<script>
if (!config.commands.collapseTiddler) return;
var here=story.findContainingTiddler(place); if (!here) return;
config.commands.collapseOthers.handler(null,here,here.getAttribute('tiddler'));
</script>
/***
|Name|FramedLinksPlugin|
|Source|http://www.TiddlyTools.com/#FramedLinksPlugin|
|Version|1.1.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|createExternalLink|
|Options|##Configuration|
|Description|clicking an external link opens an IFRAME following the link instead of opening a new tab/window|
This plugin causes clicks on external links to be rendered as inline frames (~IFRAMEs) instead of opening new browser tabs/windows.
!!!!!Usage
<<<
Use standard TiddlyWiki external link syntax into your tiddler content. If {{{chkFramedLinks}}} is enabled or the tiddler is tagged with 'framedLinks' (see Configuration), then whenever you click the external link an IFRAME will be dynamically added to the content. Clicking on the link again removes the IFRAME. Hold down any modifier (shift, control, or alt) while clicking a link ''temporarily'' bypasses the IFRAME handling and use the standard link handling behavior.
<<<
!!!!!Configuration
<<<
<<option chkFramedLinks>> display inline frames for all external links
{{{<<option chkFramedLinks>>}}}
<<option chkFramedLinksTag>> display inline frames for external links in tiddlers tagged with: <<option txtFramedLinksTag>>
{{{<<option chkFramedLinksTag>> <<option txtFramedLinksTag>>}}}
IFRAME size (CSS units: %, em, px, cm, in) - width: <<option txtFrameWidth>> height: <<option txtFrameHeight>>
{{{<<option txtFrameWidth>> <<option txtFrameHeight>>}}}
<<<
!!!!!Examples
<<<
Try these links:
*http://www.TiddlyWiki.com
*http://www.TiddlyTools.com
*http://groups.google.com/group/TiddlyWiki/topics
<<<
!!!!!Revisions
<<<
2008.11.14 [1.1.1] fixed handling for external links embedded in //shadow// tiddlers
2008.09.13 [1.1.0] added support to selectively enable embedded IFRAMEs if the containing tiddler is tagged with 'framedLinks'
2007.11.29 [1.0.5] added slider animation and improved CSS handling for IFRAME height/width to maximize display area
2007.11.29 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.FramedLinksPlugin= {major: 1, minor: 1, revision: 1, date: new Date(2008,11,14)};
var co=config.options; // abbreviation
if (co.chkFramedLinks==undefined) co.chkFramedLinks=false;
if (co.chkFramedLinksTag==undefined) co.chkFramedLinksTag=true;
if (co.txtFramedLinksTag==undefined) co.txtFramedLinksTag="framedLinks";
if (co.txtFrameWidth==undefined) co.txtFrameWidth="100%";
if (co.txtFrameHeight==undefined) co.txtFrameHeight="80%";
window.framedLinks_createExternalLink=createExternalLink;
window.createExternalLink=function(place,url)
{
var link=this.framedLinks_createExternalLink.apply(this,arguments);
link.onclick=function(ev) { var e=ev?ev:window.event;
var co=config.options; // abbreviation
var here=story.findContainingTiddler(this);
if (here) var tid=store.getTiddler(here.getAttribute("tiddler"));
var enabled=co.chkFramedLinks || co.chkFramedLinksTag && tid && tid.isTagged(co.txtFramedLinksTag);
if (!enabled || e.ctrlKey || e.shiftKey || e.altKey) return; // BYPASS
var p=this.parentNode;
var f=this.nextSibling?this.nextSibling.firstChild:null; // get the IFRAME... maybe...
var w=co.txtFrameWidth; if (!w || !w.length) w="100%";
var h=co.txtFrameHeight; if (!h || !h.length) h="80%";
if (h.indexOf("%")) h=(findWindowHeight()*h.replace(/%/,"")/100)+"px"; // calc height as % of window
var showing=f && f.nodeName.toUpperCase()=="IFRAME"; // does IFRAME really exist?
var stretchCell=p.nodeName.toUpperCase()=="TD" && w.indexOf("%")!=-1 && w.replace(/%/,"")>=100;
if (!showing) { // create an iframe
link.style.display="block"; // force IFRAME onto line following link
if (stretchCell) { p.setAttribute("savedWidth",p.style.width); p.style.width="100%"; } // adjust TD so IFRAME stretches
var wrapper=createTiddlyElement(null,"span"); // wrapper for slider animation
wrapper.setAttribute("url",this.href); // for async loading of frame after animation completes
var f=createTiddlyElement(wrapper,"iframe"); // create IFRAME
f.style.backgroundColor="#fff"; f.style.width=w; f.style.height=h;
p.insertBefore(wrapper,this.nextSibling);
function loadURL(wrapper) { var f=wrapper.firstChild; var url=wrapper.getAttribute("url");
var d=f.contentDocument?f.contentDocument:(f.contentWindow?f.contentWindow.document:f.document);
d.open(); d.writeln("<html>connecting to "+url+"</html>"); d.close();
try { f.src=url; } // if the iframe can't handle the href
catch(e) { alert(e.description?e.description:e.toString()); } // ... then report the error
window.scrollTo(0,ensureVisible(wrapper));
}
if (!co.chkAnimate) loadURL(wrapper);
else {
var morph=new Slider(wrapper,true);
morph.callback=loadURL;
morph.properties.push({style: 'width', start: 0, end: 100, template: '%0%'});
anim.startAnimating(morph);
}
} else { // remove iframe
link.style.display="inline"; // restore link style
if (stretchCell) p.style.width=p.getAttribute("savedWidth"); // restore previous width of TD
if (!co.chkAnimate) p.removeChild(f.parentNode);
else {
var morph=new Slider(f.parentNode,false,false,"all");
morph.properties.push({style: 'width', start: 100, end: 0, template: '%0%'});
anim.startAnimating(morph);
}
}
e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); return false;
}
return link;
}
//}}}
[[Three Blind Mice]]
[[howl.com!]]
[[An Invitation...]]
[[Hotter Than Hell]]
[[Meat!]]
[[English is Tuff Stough]]
[[This Crazy Language]]
<<tiddler {{"Hide"+"Tiddler"+"Background"}}>>''__The following [[setup instructions|GettingStarted]] outline the basic steps for configuring your personal tiddlyblog document:__''
{{big{
# get a copy{{normal{
Begin by transferring a copy of this ~QuickStart™ document onto your own computer: {{big green{[[download now!|http://www.tiddlytools.com/download.php?file=quickstart/tiddlyblog.html]]}}}}}}
# open local copy{{normal{
After the file is saved to your filesystem, close ''//this//'' browser/tab window and ''open the //local// file you just saved''.}}}
# set titles{{normal{
Change content in SiteTitle, SiteSubtitle}}}
# set content{{normal{
Change content in [[Welcome]], [[About|AboutThisBlog]], [[Contact|ContactTheAuthor]], [[SiteNews]] and [[Credits]]}}}
# set default tiddlers{{normal{
Edit [[DefaultTiddlers]] to select which tiddlers will be displayed at startup. The current definition is: {{block{<<wikify "{{{\n%0\n}}}\n" {{store.getTiddlerText("DefaultTiddlers")}}>>Note: the {{{[tag[startup]]}}} syntax automatically includes all tiddlers tagged with<<tag startup>>(if any). This allows you to quickly add/remove individual tiddlers from the initial display simply by setting/clearing the<<tag startup>>tag on those tiddlers, rather than manually editing the list in DefaultTiddlers.
}}}}}}
# set styles //(optional)//{{normal{
If desired, edit the StyleSheet to select your preferred background textures (if any), by changing the following syntax (near the end of the tiddler):{{block{
<<<
''//plain://''
{{{
/* [[OFF_StyleSheetWood]] [[OFF_StyleSheetStone]] */
}}}
or ''//stone://''
{{{
/* [[OFF_StyleSheetWood]] */ [[StyleSheetStone]]
}}}
or ''//wood://''
{{{
[[StyleSheetWood]] /* [[OFF_StyleSheetStone]] */
}}}
Note: StyleSheetWood and StyleSheetStone use textured background images that are stored in tiddlers as //base64 text-encoded// {{{data:}}} ~URLs that are ''not currently supported by Internet Explorer'', which will display solid colors instead.
<<<
}}}}}}
# set preferences //(optional)//{{normal{
If desired, edit the [[cookieJar]] to add, remove, or adjust hard-coded plugin preferences (see individual plugins for details). Current settings are:
<<tiddler cookieJar>>}}}
# set ~TiddlySpot ID //(optional)//{{normal{
<<<
If you are using ~TiddlySpot to host your document:
# enter your ~TiddlySpot ID: <<option txtUploadUserName>>
# press <html><hide linebreaks><input type="button" value="update" onclick="
var tid='TspotSetupPlugin';
var txt=store.getTiddlerText(tid); if (!txt) return;
if (!confirm('Are you sure you want to update \x22'+tid+'\x22?')) return;
txt=txt.replace(/ENTER_YOUR_ID_HERE/g,config.options.txtUploadUserName);
store.saveTiddler(tid,tid,txt,tid.modifier,tid.modified,tid.tags,tid.fields);
story.displayTiddler(story.findContainingTiddler(this),tid);
"></html> to set the value into TspotSetupPlugin.
# The change will take effect after you save-and-reload the //local// document.
<<<
}}}
# remove samples{{normal{
Delete the sample tiddlers (tagged with <<tag sample>>):<br><<list filter [tag[sample]]>>}}}
# done{{normal{
''That's it!''... after you save-and-reload the document, your personal tiddlyblog will be ready to use.}}}
}}}
/***
|Name|GotoPlugin|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Documentation|http://www.TiddlyTools.com/#GotoPluginInfo|
|Version|1.8.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||
|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//.'' As you type, a list of possible matches 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.
!!!Documentation
>see [[GotoPluginInfo]]
!!!Configuration
<<<
*Match titles only after {{twochar{<<option txtIncrementalSearchMin>>}}} or more characters are entered.<br>Use down-arrow to start matching with shorter input. //Note: This option value is also set/used by [[SearchOptionsPlugin]]//.
*To set the maximum height of the listbox, you can create a tiddler tagged with <<tag systemConfig>>, containing:
//{{{
config.macros.gotoTiddler.listMaxSize=10; // change this number
//}}}
<<<
!!!Revisions
<<<
2009.03.23 [1.8.0] added txtIncrementalSearchMin (default=3). Avoids fetching long lists. Use down arrow to force search with short input.
|please see [[GotoPluginInfo]] for additional revision details|
2006.05.05 [0.0.0] started
<<<
!!!Code
***/
//{{{
version.extensions.GotoPlugin= {major: 1, minor: 8, revision: 0, date: new Date(2009,3,23)};
// automatically tweak shadow SideBarOptions to add <<gotoTiddler>> macro above <<search>>
config.shadowTiddlers.SideBarOptions=config.shadowTiddlers.SideBarOptions.replace(/<<search>>/,"{{button{goto}}}\n<<gotoTiddler>><<search>>");
if (config.options.txtIncrementalSearchMin===undefined)
config.options.txtIncrementalSearchMin=3;
config.macros.gotoTiddler= {
listMaxSize: 10,
listHeading: 'Found %0 matching title%1...',
searchItem: "Search for '%0'...",
handler:
function(place,macroName,params,wikifier,paramString,tiddler) {
var quiet =params.contains("quiet");
var search =params.contains("search");
params = paramString.parseParams("anon",null,true,false,false);
var instyle =getParam(params,"inputstyle","");
var liststyle =getParam(params,"liststyle","");
var filter =getParam(params,"filter","");
var html=this.html;
var keyevent=window.event?"onkeydown":"onkeypress"; // IE event fixup for ESC handling
html=html.replace(/%keyevent%/g,keyevent);
html=html.replace(/%search%/g,search);
html=html.replace(/%quiet%/g,quiet);
html=html.replace(/%instyle%/g,instyle);
html=html.replace(/%liststyle%/g,liststyle);
html=html.replace(/%filter%/g,filter);
if (config.browser.isIE) html=this.IEtableFixup.format([html]);
createTiddlyElement(place,"span").innerHTML=html;
},
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 title text... ENTER=goto, SHIFT-ENTER=search for text, DOWN=select from list"\
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,%quiet%,%search%);">\
<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);"\
onclick="return config.macros.gotoTiddler.processItem(this.value,this.form.gotoTiddler,this);">\
</select><input name="filter" type="hidden" value="%filter%">\
</form>',
IEtableFixup:
"<table style='width:100%;display:inline;padding:0;margin:0;border:0;'>\
<tr style='padding:0;margin:0;border:0;'><td style='padding:0;margin:0;border:0;'>\
%0</td></tr></table>",
getItems:
function(val,filter) {
if (!this.items.length || val.length<2) { // starting new search, refresh cached list of tiddlers/shadows/tags
this.items=new Array();
if (filter.length) {
var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
var tiddlers=store.sortTiddlers(fn.apply(store,[filter]),'title');
} else
var tiddlers=store.getTiddlers("title","excludeLists");
for(var t=0; t<tiddlers.length; t++) this.items.push(tiddlers[t].title);
if (!filter.length) {
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,quiet,search) {
var key=event.keyCode;
var list=here.form.list;
var filter=here.form.filter;
// non-printing chars bubble up, except for a few:
if (key<48) switch(key) {
// backspace=8, enter=13, space=32, up=38, down=40, delete=46
case 8: case 13: case 32: case 38: 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); }
// make sure list is shown (unless quiet option or below input minimum)
list.style.display=(quiet||here.value.length<config.options.txtIncrementalSearchMin)?"none":"block";
// non-blank input... enter=show/create tiddler, SHIFT-enter=search for text
if (key==13) return this.processItem(event.shiftKey?'*':here.value,here,list);
// up or down key... shows and moves to list...
if (key==38 || key==40) { list.style.display="block"; list.focus(); }
// if list is showing, fill it with found results...
if (list.style.display!="none") {
var indent='\xa0\xa0\xa0';
var found = this.getItems(here.value,filter.value); // find matching items...
found.sort(); // alpha by title
while (list.length > 0) list.options[0]=null; // clear list
var hdr=this.listHeading.format([found.length,found.length==1?"":"s"]);
list.options[0]=new Option(hdr,"",false,false);
for (var t=0; t<found.length; t++) list.options[list.length]=
new Option(indent+found[t]+this.getItemSuffix(found[t]),found[t],false,false);
if (search)
list.options[list.length]=new Option(this.searchItem.format([here.value]),"*",false,false);
list.size=(list.length<this.listMaxSize?list.length:this.listMaxSize); // resize list...
list.selectedIndex=key==38?list.length-1:key==40?1:0;
}
return true; // key bubbles up
},
selectKeyHandler:
function(event,list,editfield) {
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); return this.keyProcessed(event); }
return true; // key bubbles up
},
processItem:
function(title,here,list) {
if (!title.length) return;
list.style.display='none';
if (title=="*") { story.search(here.value); return false; } // do full-text search
here.value=title;
story.displayTiddler(null,title); // show selected tiddler
return false;
}
}
//}}}
/***
|Name|HTMLFormattingPlugin|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.4.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||
|Overrides|'HTML' formatter|
|Description|embed wiki syntax formatting inside of HTML content|
The ~HTMLFormatting plugin allows you to ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Documentation
>see [[HTMLFormattingPluginInfo]]
!!!!!Revisions
<<<
2009.01.05 [2.4.0] in wikifyTextNodes(), pass w.highlightRegExp and w.tiddler to wikify() so that search term highlighting and tiddler-relative macro processing will work
| see [[HTMLFormattingPluginInfo]] for additional revision details |
2005.06.26 [1.0.0] Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
!!!!!Code
***/
//{{{
version.extensions.HTMLFormattingPlugin= {major: 2, minor: 4, revision: 0, date: new Date(2009,1,5)};
// 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];
// if <nowiki> is present, just let browser handle it!
if (html.indexOf('<nowiki>')!=-1)
createTiddlyElement(w.output,"span").innerHTML=html;
else {
// if <hide linebreaks> is present, suppress wiki-style literal handling of newlines
if (html.indexOf('<hide linebreaks>')!=-1) html=html.replace(/\n/g,' ');
// remove all \r's added by IE textarea and mask newlines and macro brackets
html=html.replace(/\r/g,'').replace(/\n/g,'\\n').replace(/<</g,'%%(').replace(/>>/g,')%%');
// create span, let browser parse HTML
var e=createTiddlyElement(w.output,"span"); e.innerHTML=html;
// then re-render text nodes as wiki-formatted content
wikifyTextNodes(e,w);
}
w.nextMatch = this.lookaheadRegExp.lastIndex; // continue parsing
}
}
}
// wikify #text nodes that remain after HTML content is processed (pre-order recursion)
function wikifyTextNodes(theNode,w)
{
function unmask(s) { return s.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n'); }
switch (theNode.nodeName.toLowerCase()) {
case 'style': case 'option': case 'select':
theNode.innerHTML=unmask(theNode.innerHTML);
break;
case 'textarea':
theNode.value=unmask(theNode.value);
break;
case '#text':
var txt=unmask(theNode.nodeValue);
var newNode=createTiddlyElement(null,"span");
theNode.parentNode.replaceChild(newNode,theNode);
wikify(txt,newNode,highlightHack,w.tiddler);
break;
default:
for (var i=0;i<theNode.childNodes.length;i++)
wikifyTextNodes(theNode.childNodes.item(i),w); // recursion
break;
}
}
//}}}
/%
|Name|HideTiddlerBackground|
|Source|http://www.TiddlyTools.com/#HideTiddlerBackground|
|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|hide a tiddler's background and border (if any)|
Usage: <<tiddler HideTiddlerBackground>>
%/<script>
var t=story.findContainingTiddler(place);
if (!t || t.id=="HideTiddlerBackground") return;
var nodes=t.getElementsByTagName("*");
for (var i=0; i<nodes.length; i++) if (hasClass(nodes[i],"viewer")) {
var s=nodes[i].style;
s.backgroundImage="none";
s.backgroundColor="transparent"
s.borderColor="transparent";
s.borderWidth=0;
s.margin=0;
s.padding=0;
break;
}
</script>
/%
|Name|HideTiddlerTags|
|Source|http://www.TiddlyTools.com/#HideTiddlerTags|
|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|hide a tiddler's tagged/tagging display elements|
Usage: <<tiddler HideTiddlerTags>>
%/<script>
var t=story.findContainingTiddler(place);
if (!t || t.id=="tiddlerHideTiddlerTags") return;
var nodes=t.getElementsByTagName("div");
for (var i=0; i<nodes.length; i++)
if (hasClass(nodes[i],"tagged"))
nodes[i].style.display="none";
</script>
/%
|Name|HideTiddlerTitle|
|Source|http://www.TiddlyTools.com/#HideTiddlerTitle|
|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|hide a tiddler's title display elements (name, dates, and author)|
Usage: <<tiddler HideTiddlerTitle>>
%/<script>
var t=story.findContainingTiddler(place);
if (!t || t.id=="tiddlerHideTiddlerTitle") return;
var nodes=t.getElementsByTagName("*");
for (var i=0; i<nodes.length; i++)
if (hasClass(nodes[i],"title")||hasClass(nodes[i],"subtitle"))
nodes[i].style.display="none";
</script>
/%
Description: Hotter Than Hell
%/From "Applied Optics" vol. 11, A14, 1972
The temperature of Heaven can be rather accurately computed. Our authority is Isaiah 30:26:
>"Moreover, the light of the Moon shall be as the light of the Sun and the light of the Sun shall be sevenfold, as the light of seven days."
Thus Heaven receives from the Moon as much radiation as we do from the Sun, and in addition 7*7 (49) times as much as the Earth does from the Sun, or 50 times in all. The light we receive from the Moon is one 1/10,000 of the light we receive from the Sun, so we can ignore that... The radiation falling on Heaven will heat it to the point where the heat lost by radiation is just equal to the heat received by radiation, i.e., Heaven loses 50 times as much heat as the Earth by radiation. Using the Stefan-Boltzmann law for radiation, (H/E)^4 = 50, where E is the absolute temperature of the earth (-300K), gives H as 798K (525C).
The exact temperature of Hell cannot be computed ... [However] Revelations 21:8 says:
>"But the fearful, and unbelieving ... shall have their part in the lake which burneth with fire and brimstone."
A lake of molten brimstone means that its temperature must be at or below the boiling point, 444.6C.
We have, then, that Heaven, at 525C is hotter than Hell at 445C.
/***
|Name|ImageSizePlugin|
|Source|http://www.TiddlyTools.com/#ImageSizePlugin|
|Version|1.2.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin,formatter|
|Requires||
|Overrides|'image' formatter|
|Description|adds support for resizing images|
This plugin adds optional syntax to scale an image to a specified width and height and/or interactively resize the image with the mouse.
!!!!!Usage
<<<
The extended image syntax is:
{{{
[img(w+,h+)[...][...]]
}}}
where ''(w,h)'' indicates the desired width and height (in CSS units, e.g., px, em, cm, in, or %). Use ''auto'' (or a blank value) for either dimension to scale that dimension proportionally (i.e., maintain the aspect ratio). You can also calculate a CSS value 'on-the-fly' by using a //javascript expression// enclosed between """{{""" and """}}""". Appending a plus sign (+) to a dimension enables interactive resizing in that dimension (by dragging the mouse inside the image). Use ~SHIFT-click to show the full-sized (un-scaled) image. Use ~CTRL-click to restore the starting size (either scaled or full-sized).
<<<
!!!!!Examples
<<<
{{{
[img(100px+,75px+)[images/meow2.jpg]]
}}}
[img(100px+,75px+)[images/meow2.jpg]]
{{{
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img( 1%+,+)[images/meow.gif]]
}}}
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img( 1%+,+)[images/meow.gif]]
{{tagClear{
}}}
<<<
!!!!!Revisions
<<<
2009.02.24 [1.2.1] cleanup width/height regexp, use '+' suffix for resizing
2009.02.22 [1.2.0] added stretchable images
2008.01.19 [1.1.0] added evaluated width/height values
2008.01.18 [1.0.1] regexp for "(width,height)" now passes all CSS values to browser for validation
2008.01.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImageSizePlugin= {major: 1, minor: 2, revision: 1, date: new Date(2009,2,24)};
//}}}
//{{{
var f=config.formatters[config.formatters.findByField("name","image")];
f.match="\\[[<>]?[Ii][Mm][Gg](?:\\([^,]*,[^\\)]*\\))?\\[";
f.lookaheadRegExp=/\[([<]?)(>?)[Ii][Mm][Gg](?:\(([^,]*),([^\)]*)\))?\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg;
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 width=lookaheadMatch[3];
var height=lookaheadMatch[4];
var tooltip=lookaheadMatch[5];
var src=lookaheadMatch[6];
var link=lookaheadMatch[7];
// 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";
if(width||height) {
var x=width.trim(); var y=height.trim();
var stretchW=(x.substr(x.length-1,1)=='+'); if (stretchW) x=x.substr(0,x.length-1);
var stretchH=(y.substr(y.length-1,1)=='+'); if (stretchH) y=y.substr(0,y.length-1);
if (x.substr(0,2)=="{{")
{ try{x=eval(x.substr(2,x.length-4))} catch(e){displayMessage(e.description||e.toString())} }
if (y.substr(0,2)=="{{")
{ try{y=eval(y.substr(2,y.length-4))} catch(e){displayMessage(e.description||e.toString())} }
img.style.width=x.trim(); img.style.height=y.trim();
config.formatterHelpers.addStretchHandlers(img,stretchW,stretchH);
}
if(tooltip) img.title = tooltip;
// GET IMAGE SOURCE
if (config.macros.attach && config.macros.attach.isAttachment(src))
src=config.macros.attach.getAttachment(src); // see [[AttachFilePluginFormatters]]
else if (config.formatterHelpers.resolvePath) { // see [[ImagePathPlugin]]
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(src,true);
}
img.src=src;
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
config.formatterHelpers.addStretchHandlers=function(e,stretchW,stretchH) {
e.title=((stretchW||stretchH)?'DRAG=stretch/shrink, ':'')
+'SHIFT-CLICK=show full size, CTRL-CLICK=restore initial size';
e.statusMsg='width=%0, height=%1';
e.style.cursor='move';
e.originalW=e.style.width;
e.originalH=e.style.height;
e.minW=Math.max(e.offsetWidth/20,10);
e.minH=Math.max(e.offsetHeight/20,10);
e.stretchW=stretchW;
e.stretchH=stretchH;
e.onmousedown=function(ev) { var ev=ev||window.event;
this.sizing=true;
this.startX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
this.startY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
this.startW=this.offsetWidth;
this.startH=this.offsetHeight;
return false;
};
e.onmousemove=function(ev) { var ev=ev||window.event;
if (this.sizing) {
var s=this.style;
var currX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
var currY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
var newW=(currX-this.offsetLeft)/(this.startX-this.offsetLeft)*this.startW;
var newH=(currY-this.offsetTop )/(this.startY-this.offsetTop )*this.startH;
if (this.stretchW) s.width =Math.floor(Math.max(newW,this.minW))+'px';
if (this.stretchH) s.height=Math.floor(Math.max(newH,this.minH))+'px';
clearMessage(); displayMessage(this.statusMsg.format([s.width,s.height]));
}
return false;
};
e.onmouseup=function(ev) { var ev=ev||window.event;
if (ev.shiftKey) { this.style.width=this.style.height=''; }
if (ev.ctrlKey) { this.style.width=this.originalW; this.style.height=this.originalH; }
this.sizing=false;
clearMessage();
return false;
};
e.onmouseout=function(ev) { var ev=ev||window.event;
this.sizing=false;
clearMessage();
return false;
};
}
//}}}
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.4|
|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|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2009.02.26 [1.9.4] in $(), handle leading '#' on ID for compatibility with JQuery syntax
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 3, date: new Date(2008,6,11)};
config.formatters.push( {
name: "inlineJavascript",
match: "\\<script",
lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
handler: function(w) {
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var src=lookaheadMatch[1];
var label=lookaheadMatch[2];
var tip=lookaheadMatch[3];
var key=lookaheadMatch[4];
var show=lookaheadMatch[5];
var code=lookaheadMatch[6];
if (src) { // load a script library
// make script tag, set src, add to body to execute, then remove for cleanup
var script = document.createElement("script"); script.src = src;
document.body.appendChild(script); document.body.removeChild(script);
}
if (code) { // there is script code
if (show) // show inline script code in tiddler output
wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
if (label) { // create a link to an 'onclick' script
// add a link, define click handler, save code in link (pass 'place'), set link attributes
var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
link.code="function _out(place){"+fixup+"\n};_out(this);"
link.tiddler=w.tiddler;
link.onclick=function(){
this.bufferedHTML="";
try{ var r=eval(this.code);
if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
if(this.bufferedHTML.length)
s.innerHTML=this.bufferedHTML;
if((typeof(r)==="string")&&r.length) {
wikify(r,s,null,this.tiddler);
return false;
} else return r!==undefined?r:false;
} catch(e){alert(e.description||e.toString());return false;}
};
link.setAttribute("title",tip||"");
var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
link.setAttribute("href",URIcode);
link.style.cursor="pointer";
if (key) link.accessKey=key.substr(0,1); // single character only
}
else { // run inline script code
var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
var c="function _out(place){"+fixup+"\n};_out(w.output);";
try { var out=eval(c); }
catch(e) { out=e.description?e.description:e.toString(); }
if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
}
}
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
}
} )
//}}}
// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
if(limit > 0) text = text.substr(0,limit);
var wikifier = new Wikifier(text,formatter,null,tiddler);
return wikifier.wikifyPlain();
}
//}}}
// // GLOBAL FUNCTION: $(...) -- 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=='undefined') { function $(id) { return document.getElementById(id.replace(/^#/,'')); } }
//}}}
<<tiddler AutoRefresh with: force>><<tiddler HideTiddlerBackground>><<tiddler HideTiddlerTags>>{{transparent smallform{<<faqViewer journal 'viewer scrollbars' -title>>}}}
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
{{groupbox{/%
STORIES
%/{{floatright{<script>
place.style.display=readOnly?'none':'inline';
</script><<saveStory ask "add" "remember the currently displayed set of tiddlers">>}}}''{{big{[[Stories|story]]}}}''
{{transparent{<<openStory list>>}}}/%
JOURNAL ENTRIES
%/{{borderbottom{
{{floatright{<script>
place.style.display=readOnly?'none':'inline';
</script><<clickify newJournal tag:journal label:"add" prompt:"create a new journal entry"
title:{{ prompt('enter a title','NewJournal '+new Date().formatString('YYYY0MM0DD 0hh0mm0ss')) }}
text:{{ store.getTiddlerText('BlankJournal','').replace(/\$1/g,new Date().formatString('DDD, MMM DDth, YYYY hh12:0mm:0ss am')) }}
>>}}}''{{big{[[Entries|JournalViewer]]}}}''}}}{{fine scroll{<<list filter [tag[journal]][sort[-created]]>>}}}/%
BOOKMARKS
%/{{borderbottom{
{{floatright{<script>
place.style.display=readOnly?'none':'inline';
</script><<clickify newTiddler tag:bookmark label:"add" prompt:"create a new bookmark (URL)"
title:{{ prompt('enter a bookmark title','NewBookmark') }}
text:{{ store.getTiddlerText('BlankBookmark','') }}
>>}}}''{{big{[[Bookmarks|MiniBrowser]]}}}''}}}{{fine scroll{<<list filter [tag[bookmark]]>>}}}/%
END GROUPBOX
%/}}}/%
%/@@display:block;height:.5em;@@/% SPACER
CALENDAR
%/{{center big{
<<slider chkShowCalendar [[MainMenu##calendarMacro]] "calendar" "show a month-at-a-glance calendar of tiddler changes">>}}}/%
!calendarMacro
{{normal{{{center{<<calendar thismonth>>}}}}}}
!end
INFO LINKS
%/{{center{
[[about|Does this taste right to you?]] [[contact|ContactTheAuthor]] [[credits|Credits]]}}}/%
SITE NEWS
%/{{center fine italic{<hr>@@font-family:Trebuchet MS;<<QOTD SiteNews norandom 60000>>@@<hr>}}}/%
TOGGLE SINGLEPAGE
%/{{center fine{<<option chkSinglePageMode>> show one tiddler at a time}}}
/***
|Name|MatchTagsPlugin|
|Source|http://www.TiddlyTools.com/#MatchTagsPlugin|
|Documentation|http://www.TiddlyTools.com/#MatchTagsPluginInfo|
|Version|2.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|plugin|
|Requires||
|Overrides||
|Description|'tag matching' with full boolean expressions (AND, OR, NOT, and nested parentheses)|
!!!!!Documentation
> see [[MatchTagsPluginInfo]]
!!!!!Revisions
<<<
2008.09.04 [2.0.0] added "report" and "panel" options to generate formatted results and store in a tiddler. Also, added config.macros.matchTags.formatList(place,fmt,sep) API to return formatted output for use with other plugins/scripts
| please see [[MatchTagsPluginInfo]] for additional revision details |
2008.02.28 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.MatchTagsPlugin= {major: 2, minor: 0, revision: 0, date: new Date(2008,9,4)};
// store.getMatchingTiddlers() processes boolean expressions for tag matching
// sortfield (optional) sets sort order for tiddlers - default=title
// tiddlers (optional) use alternative set of tiddlers (instead of current store)
TiddlyWiki.prototype.getMatchingTiddlers = function(tagexpr,sortfield,tiddlers) {
var debug=config.options.chkDebug; // abbreviation
var cmm=config.macros.matchTags; // abbreviation
var r=[]; // results are an array of tiddlers
var tids=tiddlers||store.getTiddlers(sortfield||"title");
if (tiddlers && sortfield) store.sortTiddlers(tids,sortfield);
if (debug) displayMessage(cmm.msg1.format([tids.length]));
// try simple lookup to quickly find single tags or tags that
// contain boolean operators as literals, e.g. "foo and bar"
for (var t=0; t<tids.length; t++)
if (tids[t].isTagged(tagexpr)) r.pushUnique(tids[t]);
if (r.length) {
if (debug) displayMessage(cmm.msg4.format([r.length,tagexpr]));
return r;
}
// convert expression into javascript code with regexp tests,
// so that "tag1 AND ( tag2 OR NOT tag3 )" becomes
// "/\~tag1\~/.test(...) && ( /\~tag2\~/.test(...) || ! /\~tag3\~/.test(...) )"
// normalize whitespace, tokenize operators, delimit with "~"
var c=tagexpr.trim(); // remove leading/trailing spaces
c = c.replace(/\s+/ig," "); // reduce multiple spaces to single spaces
c = c.replace(/\(\s?/ig,"~(~"); // open parens
c = c.replace(/\s?\)/ig,"~)~"); // close parens
c = c.replace(/(\s|~)?&&(\s|~)?/ig,"~&&~"); // &&
c = c.replace(/(\s|~)AND(\s|~)/ig,"~&&~"); // AND
c = c.replace(/(\s|~)?\|\|(\s|~)?/ig,"~||~"); // ||
c = c.replace(/(\s|~)OR(\s|~)/ig,"~||~"); // OR
c = c.replace(/(\s|~)?!(\s|~)?/ig,"~!~"); // !
c = c.replace(/(^|~|\s)NOT(\s|~)/ig,"~!~"); // NOT
c = c.replace(/(^|~|\s)NOT~\(/ig,"~!~("); // NOT(
// change tag terms to regexp tests
var terms=c.split("~"); for (var i=0; i<terms.length; i++) { var t=terms[i];
if (/(&&)|(\|\|)|[!\(\)]/.test(t) || t=="") continue; // skip operators/parens/spaces
if (t==config.macros.matchTags.untaggedKeyword)
terms[i]="tiddlertags=='~~'"; // 'untagged' tiddlers
else
terms[i]="/\\~"+t+"\\~/.test(tiddlertags)";
}
c=terms.join(" ");
if (debug) { displayMessage(cmm.msg2.format([tagexpr])); displayMessage(cmm.msg3.format([c])); }
// scan tiddlers for matches
for (var t=0; t<tids.length; t++) {
// assemble tags from tiddler into string "~tag1~tag2~tag3~"
var tiddlertags = "~"+tids[t].tags.join("~")+"~";
try { if(eval(c)) r.push(tids[t]); } // test tags
catch(e) { // error in test
displayMessage(cmm.msg2.format([tagexpr]));
displayMessage(cmm.msg3.format([c]));
displayMessage(e.toString());
break; // skip remaining tiddlers
}
}
if (debug) displayMessage(cmm.msg4.format([r.length,tagexpr]));
return r;
}
//}}}
//{{{
config.macros.matchTags = {
msg1: "scanning %0 input tiddlers",
msg2: "looking for '%0'",
msg3: "using expression: '%0'",
msg4: "found %0 tiddlers matching '%1'",
noMatch: "no matching tiddlers",
untaggedKeyword: "-",
untaggedLabel: "no tags",
untaggedPrompt: "show tiddlers with no tags",
defTiddler: "MatchingTiddlers",
defFormat: "%0",
defSeparator: "\n",
reportHeading: "Found %0 tiddlers tagged with: '{{{%1}}}'\n----\n",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var mode=params[0]?params[0].toLowerCase():'';
if (mode=="inline")
params.shift();
if (mode=="report" || mode=="panel") {
params.shift();
var target=params.shift()||this.defTiddler;
}
if (mode=="popup") {
params.shift();
if (params[0]&¶ms[0].substr(0,6)=="label:") var label=params.shift().substr(6);
if (params[0]&¶ms[0].substr(0,7)=="prompt:") var prompt=params.shift().substr(7);
} else {
var fmt=(params.shift()||this.defFormat).unescapeLineBreaks();
var sep=(params.shift()||this.defSeparator).unescapeLineBreaks();
}
var sortBy="+title";
if (params[0]&¶ms[0].substr(0,5)=="sort:") sortBy=params.shift().substr(5);
var expr = params.join(" ");
if (mode!="panel" && (!expr||!expr.trim().length)) return;
if (expr==this.untaggedKeyword)
{ var label=this.untaggedLabel; var prompt=this.untaggedPrompt };
switch (mode) {
case "popup": this.createPopup(place,label,expr,prompt,sortBy); break;
case "panel": this.createPanel(place,expr,fmt,sep,sortBy,target); break;
case "report": this.createReport(target,expr,fmt,sep,sortBy); break;
case "inline": default: this.createInline(place,expr,fmt,sep,sortBy); break;
}
},
formatList: function(tids,fmt,sep) {
var out=[];
for (var t=0; t<tids.length; t++) {
var title="[["+tids[t].title+"]]";
var who=tids[t].modifier;
var when=tids[t].modified.toLocaleString();
var text=tids[t].text;
var first=tids[t].text.split("\n")[0];
var desc=store.getTiddlerSlice(tids[t].title,"description");
desc=desc||store.getTiddlerSlice(tids[t].title,"Description");
desc=desc||store.getTiddlerText(tids[t].title+"##description");
desc=desc||store.getTiddlerText(tids[t].title+"##Description");
out.push(fmt.format([title,who,when,text,first,desc]));
}
return out.join(sep);
},
createInline: function(place,expr,fmt,sep,sortBy) {
wikify(this.formatList(store.sortTiddlers(store.getMatchingTiddlers(expr),sortBy),fmt,sep),place);
},
createPopup: function(place,label,expr,prompt,sortBy) {
var btn=createTiddlyButton(place,
(label||expr).format([expr]),
(prompt||config.views.wikified.tag.tooltip).format([expr]),
function(ev){ return config.macros.matchTags.showPopup(this,ev||window.event); });
btn.setAttribute("sortBy",sortBy);
btn.setAttribute("expr",expr);
},
showPopup: function(here,ev) {
var p=Popup.create(here); if (!p) return false;
var tids=store.getMatchingTiddlers(here.getAttribute("expr"));
store.sortTiddlers(tids,here.getAttribute("sortBy"));
var list=[]; for (var t=0; t<tids.length; t++) list.push(tids[t].title);
if (!list.length) createTiddlyText(p,this.noMatch);
else {
var b=createTiddlyButton(createTiddlyElement(p,"li"),
config.views.wikified.tag.openAllText,
config.views.wikified.tag.openAllTooltip,
function() {
var list=this.getAttribute("list").readBracketedList();
story.displayTiddlers(null,tids);
});
b.setAttribute("list","[["+list.join("]] [[")+"]]");
createTiddlyElement(p,"hr");
}
var out=this.formatList(tids," %0 ","\n"); wikify(out,p);
Popup.show(p,false);
ev.cancelBubble=true;
if(ev.stopPropagation) ev.stopPropagation();
return false;
},
createReport: function(target,expr,fmt,sep,sortBy) {
var tids=store.sortTiddlers(store.getMatchingTiddlers(expr),sortBy);
if (!tids.length) { displayMessage('no matches for: '+expr); return false; }
var msg=config.messages.overwriteWarning.format([target]);
if (store.tiddlerExists(target) && !confirm(msg)) return false;
var out=this.reportHeading.format([tids.length,expr])
out+=this.formatList(tids,fmt,sep);
store.saveTiddler(target,target,out,config.options.txtUserName,new Date(),[],{});
story.closeTiddler(target); story.displayTiddler(null,target);
},
createPanel: function(place,expr,fmt,sep,sortBy,tid) {
var html="<form style='display:inline'><!-- \
--><input type='text' name='expr' style='width:55%' title='tag expression'><!-- \
--><input type='text' name='fmt' style='width:10%' title='list item format'><!-- \
--><input type='text' name='sep' style='width:5%' title='list item separator'><!-- \
--><input type='text' name='tid' style='width:20%' title='target tiddler title'><!-- \
--><input type='button' name='go' style='width:8%' value='go' onclick=\" \
var expr=this.form.expr.value; \
if (!expr.length) { alert('Enter a boolean tag expression'); return false; } \
var fmt=this.form.fmt.value; \
if (!fmt.length) { alert('Enter the list item output format'); return false; } \
var sep=this.form.sep.value.unescapeLineBreaks(); \
var tid=this.form.tid.value; \
if (!tid.length) { alert('Enter a target tiddler title'); return false; } \
config.macros.matchTags.createReport(tid,expr,fmt,sep,'title'); \
return false;\"> \
</form>";
var s=createTiddlyElement(place,"span"); s.innerHTML=html;
var f=s.getElementsByTagName("form")[0];
f.expr.value=expr; f.fmt.value=fmt; f.sep.value=sep.escapeLineBreaks(); f.tid.value=tid;
}
};
//}}}
//{{{
// SHADOW TIDDLER for displaying default panel input form
config.shadowTiddlers.MatchTags="{{smallform{<<matchTags panel>>}}}";
//}}}
//{{{
// TWEAK core filterTiddlers() for enhanced boolean matching in [tag[...]] syntax:
// use getMatchingTiddlers instead getTaggedTiddlers
var fn=TiddlyWiki.prototype.filterTiddlers;
fn=fn.toString().replace(/getTaggedTiddlers/g,"getMatchingTiddlers");
eval("TiddlyWiki.prototype.filterTiddlers="+fn);
//}}}
//{{{
// REDEFINE core handler for enhanced boolean matching in tag:"..." paramifier
// use filterTiddlers() instead of getTaggedTiddlers() to get list of tiddlers.
config.paramifiers.tag = {
onstart: function(v) {
var tagged = store.filterTiddlers("[tag["+v+"]]");
story.displayTiddlers(null,tagged,null,false,null);
}
};
//}}}
<<tiddler HideTiddlerTags>>/%
Description: This Crazy Language
%/@@display:block;width:80%;margin:0 auto;{{medium{
{{center{
{{big{"Meat..."
(a dialogue between two extra-terrestrial beings)}}}
by Terry Bisson.
{{tiny{
from a series of stories entitled "Alien/Nation"
in the April [1991?] issue of Omni Magazine}}}
}}}
"They're made out of meat."
"Meat?"
"Meat. They're made out of meat."
"Meat?"
"There's no doubt about it. We picked several from different parts of the planet, took them aboard our recon vessels, probed them all the way through. They're completely meat."
"That's impossible. What about the radio signals? The messages to the stars."
"They use the radio waves to talk, but the signals don't come from them. The signals come from machines."
"So who made the machines? That's who we want to contact."
"They made the machines. That's what I'm trying to tell you. Meat made the machines."
"That's ridiculous. How can meat make a machine? You're asking me to believe in sentient meat."
"I'm not asking you, I 'm telling you. These creatures are the only sentient race in the sector and they're made out of meat."
"Maybe they're like the Orfolei. You know, a carbon-based intelligence that goes through a meat stage."
"Nope. They're born meat and they die meat. We studied them for several of their life spans, which didn't take too long. Do you have any idea the life span of meat?"
"Spare me. Okay, maybe they're only part meat. You know, like the Weddilei. A meat head with an electron plasma brain inside."
"Nope. We thought of that, since they do have meat heads like the Weddilei. But I told you, we probed them. They're meat all the way through."
"No brain?"
"Oh, there is a brain all right. It's just that the brain is made out of meat!"
"So... what does the thinking?"
"You're not understanding, are you? The brain does the thinking. The meat."
"Thinking meat! You're asking me to believe in thinking meat!"
"Yes, thinking meat! Conscious meat! Loving meat. Dreaming meat. The meat is the whole deal! Are you getting the picture?"
"Omigod. You're serious then. They're made out of meat."
"Finally, Yes. They are indeed made out meat. And they've been trying to get in touch with us for almost a hundred of their years."
"So what does the meat have in mind."
"First it wants to talk to us. Then I imagine it wants to explore the universe, contact other sentients, swap ideas and information. The usual."
"We're supposed to talk to meat?"
"That's the idea. That's the message they're sending out by radio. 'Hello. Anyone out there? Anyone home?' That sort of thing."
"They actually do talk, then. They use words, ideas, concepts?"
"Oh, yes. Except they do it with meat."
"I thought you just told me they used radio."
"They do, but what do you think is on the radio? Meat sounds. You know how when you slap or flap meat it makes a noise? They talk by flapping their meat at each other. They can even sing by squirting air through their meat."
"Omigod. Singing meat. This is altogether too much. So what do you advise?"
"Officially or unofficially?"
"Both."
"Officially, we are required to contact, welcome, and log in any and all sentient races or multibeings in the quadrant, without prejudice, fear, or favor. Unofficially, I advise that we erase the records and forget the whole thing."
"I was hoping you would say that."
"It seems harsh, but there is a limit. Do we really want to make contact with meat?"
"I agree one hundred percent. What's there to say?" `Hello, meat. How's it going?' But will this work? How many planets are we dealing with here?"
"Just one. They can travel to other planets in special meat containers, but they can't live on them. And being meat, they only travel through C space. Which limits them to the speed of light and makes the possibility of their ever making contact pretty slim. Infinitesimal, in fact."
"So we just pretend there's no one home in the universe."
"That's it."
"Cruel. But you said it yourself, who want to meet meat? And the ones who have been aboard our vessels, the ones you have probed? You're sure they won't remember?"
"They'll be considered crackpots if they do. We went into their heads and smoothed out their meat so that we're just a dream to them."
"A dream to meat! How strangely appropriate, that we should be meat's dream."
"And we can marked this sector unoccupied."
"Good. Agreed, officially and unofficially. Case closed. Any others? Anyone interesting on that side of the galaxy?"
"Yes, a rather shy but sweet hydrogen core cluster intelligence in a class nine star in G445 zone. Was in contact two galactic rotation ago, wants to be friendly again."
"They always come around."
"And why not? Imagine how unbearably, how unutterably cold the universe would be if one were all alone.
}}}@@
<<tiddler AutoRefresh with: force>><<tiddler HideTiddlerBackground>><<tiddler HideTiddlerTags>>{{transparent smallform{<<miniBrowser MiniBrowserFavorites>>}}}
/***
|Name|MiniBrowserPlugin|
|Source|http://www.TiddlyTools.com/#MiniBrowserPlugin|
|Version|1.4.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|PlayerPlugin (optional, recommended)|
|Overrides||
|Options|##Configuration|
|Description|embedded browser-in-browser with favorites lists and media support|
!!!!!Usage
<<<
{{{<<miniBrowser noplayer expand hidecontrols URL TiddlerName TiddlerName TiddlerName...>>}}}
* ''noplayer'' (optional)<br>disables support for embedded media player (using [[PlayerPlugin]], if installed)
* ''expand'' (optional)<br>displays minibrowser controls on two lines instead of one for increased readability, especially when long titles or URLs are displayed.
* ''hidecontrols'' (optional)<br>hide initial display of minibrowser controls (except for 'show controls' checkbox)<br>//note: if no initial URL is specified, controls will be shown anyway//
* ''URL'' (optional)<br>specifies an initial URL to open when the mini browser is rendered
* ''TiddlerName'', ''TiddlerName''... (optional)<br>indicates one or more tiddlers containing "HR-separated" lists of favorites.<br>//notes: if no tiddler is specified, [[MiniBrowserList]] is used by default. In addition, when adding/deleting favorites, the plugin automatically updates [[MiniBrowserList]], regardless of any alternative lists of favorites stored in separate tiddlers. After changes to [[MiniBrowserList]] are made, you can then use cut/paste to manually move entries from that tiddler into other tiddlers.//
<<<
!!!!!Configuration
<<<
Default mini browser size:
width: <<option txtMiniBrowserWidth>> height: <<option txtMiniBrowserHeight>>
<<<
!!!!!Example
>{{{<<miniBrowser>>}}}<br>{{smallform small{<<miniBrowser>>}}}
>{{{<<miniBrowser expand>>}}}<br>{{smallform small{<<miniBrowser expand>>}}}
>{{{<<miniBrowser hidecontrols http://www.TiddlyWiki.com>>}}}<br>{{smallform small{<<miniBrowser hidecontrols http://www.TiddlyWiki.com>>}}}
!!!!!Revisions
<<<
2008.09.30 [1.4.0] removed hard-coded 8pt fontsize. Added optional "expand" display mode to show controls on two lines instead of one for increased readability.
2008.09.16 [1.3.1] fixed getWikifiedData() when using IE (remove \r and multiple \n)
2008.08.12 [1.3.0] added support for wikifying content from favorites lists to enable use of forEachTiddler or inline script output to generate lists on the fly.
2008.08.06 [1.2.2] corrected size control buttons to use fixed width
2008.04.07 [1.2.1] added txtMiniBrowserWidth and txtMiniBrowserHeight. cleanup init handling (somewhat)
2008.04.06 [1.2.0] added support for specifying initial URL to view (suggested by Richard Berg). When opening a URL, select matching entry (if any) in bookmarks droplist. Added support for hiding minibrowser controls.
2008.01.19 [1.1.0] added support for optional extra favorites lists stored in separate tiddlers
2007.10.15 [1.0.0] combined MiniBrowser and MediaCenter inline scripts and converted to true plugin
2006.03.01 [0.0.0] inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.MiniBrowserPlugin={major: 1, minor: 4, revision: 0, date: new Date(2008,9,30)};
//}}}
//{{{
config.shadowTiddlers.MiniBrowser="<<miniBrowser>>";
//}}}
//{{{
if (config.options.txtMiniBrowserWidth==undefined) config.options.txtMiniBrowserWidth="100%";
if (config.options.txtMiniBrowserHeight==undefined) config.options.txtMiniBrowserHeight="480";
//}}}
//{{{
config.macros.miniBrowser= {
favoritesList:
"MiniBrowserList",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var noPlayer=params[0]&¶ms[0].toLowerCase()=="noplayer"; if (noPlayer) params.shift();
if (!config.macros.player) noPlayer=true; // if PlayerPlugin not installed
var expand=params[0]&¶ms[0].toLowerCase()=="expand"; if (expand) params.shift();
var hideControls=params[0]&¶ms[0].toLowerCase()=="hidecontrols"; if (hideControls) params.shift();
var url=(params[0]&&!store.tiddlerExists(params[0]))?params.shift():"";
hideControls=hideControls&&url.length; // if no initial URL, then show controls anyway
var w=config.options.txtMiniBrowserWidth;
var h=config.options.txtMiniBrowserHeight;
// create form
var guid=new Date().getTime()+Math.random().toString(); // globally unique ID
var html=this.html;
html=html.replace(/%id%/g,guid);
html=html.replace(/%noplayer%/g,noPlayer?"true":"");
html=html.replace(/%hidecontrols%/g,hideControls?"none":"block");
html=html.replace(/%bookmarksize%/g,expand?"70%":"20%");
html=html.replace(/%urlsize%/g,expand?"69.5%":"20%");
html=html.replace(/%linebreak%/g,expand?"<br>":"");
html=html.replace(/%favorites%/g,params[0]||config.macros.miniBrowser.favoritesList);
createTiddlyElement(place,"span").innerHTML=html;
// init form
document.getElementById("minibrowser_controls_"+guid).style.display=hideControls?"none":"block";
document.getElementById("minibrowser_resize_"+guid).style.display=hideControls?"none":"block";
document.getElementById("minibrowser_togglecontrols_"+guid).checked=!hideControls;
document.getElementById("minibrowser_form_"+guid).url.value=url;
document.getElementById("minibrowser_form_"+guid).w.value=w;
document.getElementById("minibrowser_form_"+guid).h.value=h;
if (noPlayer) { // hide "type" list no PlayerPlugin
document.getElementById("minibrowser_type_"+guid).style.display="none";
document.getElementById("minibrowser_url_"+guid).style.width="36%";
}
// load bookmarks droplist from HR-separated tiddler contents
var b=document.getElementById("minibrowser_bookmarks_"+guid);
while (b.options[1]) b.options[1]=null; // clear list but leave 'prompt' item
var p; while (p=params.shift()) this.getFavorites(b,p); // load custom bookmarks
if (b.length<2) this.getFavorites(b,config.macros.miniBrowser.favoritesList); // default list
// load initial URL (if any)
var place=document.getElementById("minibrowser_player_"+guid);
this.load(place,guid,"","",w,h,true,noPlayer);
this.go(document.getElementById("minibrowser_form_"+guid));
},
getFavorites: function(list,tid) {
var txt=store.getTiddlerText(tid); if (!txt||!txt.trim().length) return;
txt=this.getWikifiedData(txt);
var parts=txt.split("\n----\n");
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var label=lines.shift()||""; // 1st line=display text
var value=lines.shift()||""; // 2nd line=item value
var indent=value&&value.length?"\xa0\xa0":"";
list.options[list.length]=new Option(indent+label,value,false,false);
}
},
getWikifiedData: // wikify tiddler content, then extract text WITH newlines and HRs included
function(txt) {
var e=createTiddlyElement(document.body,"div"); wikify(txt,e);
var breaks=e.getElementsByTagName("br");
for (var b=0; b<breaks.length; b++)
breaks[b].parentNode.insertBefore(document.createTextNode("\n"),breaks[b]);
var lines=e.getElementsByTagName("hr");
for (var l=0; l<lines.length; l++)
lines[l].parentNode.insertBefore(document.createTextNode("----\n"),lines[l]);
var items=e.getElementsByTagName("li");
for (var i=0; i<items.length; i++)
items[i].parentNode.insertBefore(document.createTextNode("\n"),items[i]);
var txt=getPlainText(e);
removeNode(e);
return txt.replace(/\r*/g,"").replace(/\n\n/g,"\n");
},
load: function(place,id,type,url,w,h,showcontrols,noPlayer) {
if (noPlayer) {
if (!place) place=document.getElementById(id).parentNode;
place.innerHTML="<iframe name='"+id+"' id='"+id+"' \
src='"+url+"' width='"+w+"' height='"+h+"' \
style='background:#fff;border:1px solid'></iframe>"
} else
config.macros.player.loadURL(place,id,type,url,w,h,showcontrols);
},
go: function(f) {
var url=f.url.value.trim();
if (!url.length) url=f.url.value=f.bookmarks.value.trim();
if (!url.length) { this.done(f); return false; }
var id=f.playerID.value;
document.getElementById("minibrowser_player_"+id).style.display="block";
document.getElementById("minibrowser_controls2_"+id).style.display="block";
this.load(null,id,f.type.value,f.url.value,f.w.value,f.h.value,f.ctrls.checked,f.noPlayer.value=="true");
var matched=false; for (var i=0; i<f.bookmarks.options.length; i++) // select matching bookmark
if (f.bookmarks.options[i].value==url) { f.bookmarks.selectedIndex=i; matched=true; break; }
if (!matched) f.bookmarks.selectedIndex=0;
f.done.disabled=false;
return false;
},
done: function(f) {
var id=f.playerID.value;
this.load(null,id,null,null,f.w.value,0,f.ctrls.checked,f.noPlayer.value=="true");
document.getElementById("minibrowser_player_"+id).style.display="none";
document.getElementById("minibrowser_controls2_"+id).style.display="none";
f.done.disabled=true;
return false;
},
fit: function(place) {
var trim=89; // fudge factor to account for the other controls + padding + borders. ADJUST THIS VALUE TO FIT LAYOUT
var t=story.findContainingTiddler(place);
if (!t) { t=place; while (t && t.className!='floatingPanel') t=t.parentNode; } if (!t) return;
var w="100%"; // horizontal stretching via CSS works, but vertical stretching doesn't... so:
var h=t.offsetHeight-trim; // workaround: get containing panel/tiddler height and subtract "trim" height
var f=place.form;
this.load(null,f.playerID.value,f.type.value,f.url.value,w,h,f.ctrls.checked,f.noPlayer.value=="true"); // reload player with new size
place.form.w.value=w; place.form.h.value=h; // update width/height input fields
},
add: function(place,title) {
var v=place.value; if (!v.length) return;
var d=prompt("Please enter a description for\n"+place.value); if (!d || !d.length) return;
var who=config.options.txtUserName;
var when=new Date();
var tid=store.getTiddler(title);
var txt="%0\n%1\n----\n%2".format([d,v,tid?tid.text:""]);
store.saveTiddler(title,title,txt,who,when,tid?tid.tags:[],tid?tid.fields:{});
if (!tid) story.displayTiddler(story.findContainingTiddler(place),title);
else story.refreshTiddler(title,1,true);
var here=story.findContainingTiddler(place);
if (here) story.refreshTiddler(here.getAttribute("tiddler"),1,true);
},
del: function(place,title) {
var v=place.value; if (!v.length) return;
var d=place.options[place.selectedIndex].text; if (!d.length) return;
if (!confirm("Are you sure you want to remove this favorite?\n\n"+d+"\n"+v)) return;
var tid=store.getTiddler(title); if (!tid) return;
var who=config.options.txtUserName;
var when=new Date();
var pat='%0\n%1\n----\n'.format([d.replace(/\xa0/g,''),v]); var re=new RegExp(pat,"i");
var txt=tid.text.replace(re,"");
store.saveTiddler(title,title,txt,who,when,tid?tid.tags:[],tid?tid.fields:{});
story.refreshTiddler(title,1,true);
var here=story.findContainingTiddler(place);
if (here) story.refreshTiddler(here.getAttribute("tiddler"),1,true);
},
html: "<form id='minibrowser_form_%id%' style='display:block;margin:0;padding:0' onsubmit='return config.macros.miniBrowser.go(this);'><!-- \
--><nobr><input type='hidden' name='playerID' value='%id%'><input type='hidden' name='noPlayer' value='%noplayer%'><!-- \
--><div id='minibrowser_controls_%id%' style='display:%hidecontrols%'><!-- \
--><input type='button' value='<' title='back' style='width:3%' \
onclick='try{window.frames[\"player_%id%\"].history.go(-1)}catch(e){window.history.go(-1)}' ><!-- \
--><input type='button' value='>' title='forward' style='width:3%' \
onclick='try{window.frames[\"player_%id%\"].history.go(+1)}catch(e){window.history.go(+1)}'><!-- \
--><input type='button' value='+' title='refresh'style='width:3%' \
onclick='try{window.frames[\"player_%id%\"].location.reload()}catch(e){;}'><!-- \
--><input type='button' value='x' title='stop'style='width:3%' \
onclick='window.stop()'><!-- \
--><select name='bookmarks' id='minibrowser_bookmarks_%id%' size='1' style='width:%bookmarksize%' \
onchange='this.form.url.value=this.value; return config.macros.miniBrowser.go(this.form);'><!-- \
--><option value=''>bookmarks...</option><!-- \
--></select><!-- \
--><input type='button' value='add' title='add URL to the bookmarks' style='width:6%' \
favorites=\"%favorites%\" \
onclick='config.macros.miniBrowser.add(this.form.url,this.getAttribute(\"favorites\"));'><!-- \
--><input type='button' value='del' title='remove URL from the bookmarks' style='width:6%' \
favorites=\"%favorites%\" \
onclick='config.macros.miniBrowser.del(this.form.bookmarks,this.getAttribute(\"favorites\"));'><!-- \
--><input type='button' value='edit' title='edit the bookmarks list' style='width:6%' \
favorites=\"%favorites%\" \
onclick='story.displayTiddler(null,this.getAttribute(\"favorites\"),2)'><!-- \
-->%linebreak%<!-- \
--><select name='type' id='minibrowser_type_%id%' size='1' style='width:12%' \
onchange='var opt=this.options; for (var i=0; i<opt.length; i++) \
if (i==this.selectedIndex) opt[i].text=opt[i].text.replace(/\xa0\xa0/,\"√\"); \
else opt[i].text=opt[i].text.replace(/√/,\"\xa0\xa0\"); \
if (this.selectedIndex==0) opt[1].text=opt[1].text.replace(/\xa0\xa0/,\"√\");'><!-- \
--><option value=''>type...</option><!-- \
--><option value=''>√ auto-detect</option><!-- \
--><option value='iframe'> web page</option><!-- \
--><option value='windows'> windows media</option><!-- \
--><option value='realone'> real one</option><!-- \
--><option value='quicktime'> quicktime</option><!-- \
--><option value='flash'> flash</option><!-- \
--><option value='image'> jpg/gif/png</option><!-- \
--></select><!-- \
--><input type='text' name='url' id='minibrowser_url_%id%' size='60' value='' style='width:%urlsize%' \
onfocus='this.select()'><!-- \
--><input type='submit' value='go' title='view URL in embedded player' style='width:6%'><!-- \
--><input type='button' value='open' title='view URL in a separate player' style='width:6%' \
onclick='if (this.form.url.value.length) window.open(this.form.url.value)'><!-- \
--><input type='button' value='done' name='done' disabled title='disconnect from URL' style='width:6%' \
onclick='return config.macros.miniBrowser.done(this.form);'><!-- \
--></div><!-- \
--><div id='minibrowser_player_%id%' style='display:none;text-align:center'></div><!-- \
--><span id='minibrowser_controls2_%id%' style='margin-top:2px;display:none;'><!-- \
--><div id='minibrowser_resize_%id%' style='display:%hidecontrols%;float:right'><!-- \
--> size: <input type='text' name='w' size='3' value='' style='' \
onfocus='this.select()'><!-- \
-->x<input type='text' name='h' size='3' value='' style='' \
onfocus='this.select()'><!-- \
--> <input type='submit' value='set' style='width:5em' \
onclick='var f=this.form; \
if(!f.w.value.trim().length) f.w.value=config.options.txtMiniBrowserWidth; \
if(!f.h.value.trim().length) f.h.value=config.options.txtMiniBrowserHeight; \
config.options.txtMiniBrowserWidth=f.w.value; config.options.txtMiniBrowserHeight=f.h.value; \
saveOptionCookie(\"txtMiniBrowserWidth\"); saveOptionCookie(\"txtMiniBrowserHeight\");'><!-- \
--><input type='submit' value='reset' style='width:5em' \
onclick='var f=this.form; f.ctrls.checked=true; f.w.value=\"100%\"; f.h.value=\"480\"; \
config.options.txtMiniBrowserWidth=f.w.value; config.options.txtMiniBrowserHeight=f.h.value; \
saveOptionCookie(\"txtMiniBrowserWidth\"); saveOptionCookie(\"txtMiniBrowserHeight\");'><!-- \
--><input type='button' value='fit' title='resize player to fit containing window' style='width:5em' \
onclick='config.macros.miniBrowser.fit(this)'><!-- \
--></div><!-- \
--> <input type='checkbox' name='ctrls' id='minibrowser_togglecontrols_%id%' title='toggle minibrowser controls' CHECKED \
onclick='document.getElementById(\"minibrowser_controls_%id%\").style.display=this.checked?\"block\":\"none\"; \
document.getElementById(\"minibrowser_resize_%id%\").style.display=this.checked?\"block\":\"none\";' \
><a href='' title='toggle minibrowser controls' \
onclick='this.previousSibling.click();return false;'>show controls</a><!-- \
--></span><!-- \
--></nobr></form> \
"
}
//}}}
Main/.*
http://reiber.org/nxt/bin/view/$1
<html><iframe src="http://reiber.org/nxt/bin/view/$1" style="width:100%;height:480px"></iframe></html>
/***
|Name|MissingTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#MissingTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#MissingTiddlersPlugin|
|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|plugin|
|Requires||
|Overrides||
|Description|define alternative content for missing tiddlers|
!!!Usage
<<<
This plugin re-defines the default content for missing tiddlers, so that the following macro is automatically invoked whenever a missing tiddler is viewed:
{{{
<<missingTiddler [[title]] [[list]] [[fallback]]>>
}}}
where:
*''title'' (required)<br>specifies the title of the missing tiddler.
*''list'' (optional, default="{{{[[MissingTiddlersList]]}}}")<br>specifies the tiddler containing a list of title patterns and associated alternative content (see below)
*''fallback'' (optional, default="{{{[[MissingTiddler]]}}}")<br>specifies the tiddler containing default fallback content for all //unmatched// missing titles.
The macro first reads from the [[MissingTiddlersList]], which contains a list of alternative content to use for specific missing tiddlers. List entries are separated by "{{{----}}}". Each list entry includes two or more lines of text: the first line is a //regular expression// pattern used to match the missing title, and the remaining lines are the content to display when the missing title matches the specified pattern. To insert the title of the missing tiddler into the resulting output, you can embed {{{$1}}} as a //substitution marker// within the content. If no matching pattern is found (or [[MissingTiddlersList]] does not exist), the plugin uses fallback content from a tiddler named [[MissingTiddler]], which has a default (shadow) definition that you can customize.
<<<
!!!Revisions
<<<
2009.01.20 [1.0.0] initial release
<<<
!!!Code
***/
//{{{
version.extensions.MissingTiddlersPlugin={major: 1, minor: 0, revision: 0, date: new Date(2009,1,20)};
config.shadowTiddlers.MissingTiddler ="The tiddler '$1' doesn't yet exist. Double-click to create it.";
config.views.wikified.defaultText ='<<missingTiddler [[%0]] [[MissingTiddlersList]] [[MissingTiddler]]>>';
config.macros.missingTiddler = {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var title=params[0]||'';
var list=store.getTiddlerText(params[1]||'MissingTiddlerList','');
var out=store.getTiddlerText(params[2]||'MissingTiddler','');
var items=list.split('\n----\n');
for (var i=0; i<items.length; i++) {
var lines=items[i].split('\n');
if (title.match(new RegExp(lines.shift())))
{ out=lines.join('\n'); break; }
}
wikify(out.replace(/\$1/g,title),place);
}
}
//}}}
/%
Description: More than story telling...
%/Thursday, March 26th, 2009 5:15:50 am
{{center big{
__Something more than story telling...__}}}
Science, through inquiry, observation and analysis, seeks to provide rational explanations about the way the world around us works and, by inference and application of deductive reasoning, also attempts to offer explanations for things we believe occur, but cannot (currently) observe first-hand.
However, it is not sufficient for a scientific explanation to be merely //believable//. No matter how elegantly presented, ideas and theories are only unsupported concepts offered up as hypotheses that then require well-considered, carefully-controlled, rigorous and exacting observations and measurements -- as well as careful analysis and critical reasoning -- in order to verify the basic reproducibility and consistency of the results, before any conclusions can be considered to be "facts" or "truths"...
Even then, unlike other philosophical belief systems such as religion, scientific facts are always considered to be //provisional// truths at best. ''Science is more than mere creative story telling... rather, it is a Philosophy of Inquiry that //demands// that any new phenomena we observe must not be rejected out-of-hand, and should always be impartially considered and studied, even when it appears to refute what we previously thought was true.''
{{center{
''//"We have to live today by what truth we can get today,
and be ready tomorrow to call it falsehood." - [William James]//''
}}}
/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.9|
|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.11.15 - 2.4.9 in adjustNestedSlider(), don't make adjustments if panel is marked as 'undocked' (CSS class). In onClickNestedSlider(), SHIFT-CLICK docks panel (see [[MoveablePanelPlugin]])
|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.NestedSlidersPlugin= {major: 2, minor: 4, revision: 9, date: new Date(2008,11,15)};
// 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");
// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
window.removeCookie=function(name) {
document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
}
}
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";
// if SHIFT-CLICK, dock panel first (see [[MoveablePanelPlugin]])
if (e.shiftKey && config.macros.moveablePanel) config.macros.moveablePanel.dock(theSlider,e);
// 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")
{ try{ ctrls[c].focus(); } catch(err){;} break; }
}
}
var cookie=theTarget.sliderCookie;
if (cookie && cookie.length) {
config.options[cookie]=!isOpen;
if (config.options[cookie]!=theTarget.defOpen) window.saveOptionCookie(cookie);
else window.removeCookie(cookie); // remove cookie if slider is in default display state
}
// 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})
if (!hasClass(all[i],"floatingPanel")&&!hasClass(all[i],"sliderPanel")) all[i].style.display="none";
}
return retval;
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel) {
if (hasClass(panel,"floatingPanel") && !hasClass(panel,"undocked")) {
// see [[MoveablePanelPlugin]] for use of 'undocked'
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);
}
};
}
//}}}
/%
|Name|NextTiddler|
|Source|http://www.TiddlyTools.com/#NextTiddler|
|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|insert a link that, when clicked, closes the current tiddler and opens another one in its place|
usage: <<tiddler NextTiddler with: NewTiddlerTitle linktext>>
%/<script label="$2">
var tiddler=story.findContainingTiddler(place);
story.displayTiddler(tiddler,"$1");
story.closeTiddler(tiddler.getAttribute("tiddler")); // close self
return false;
</script>
[[Things I've Learned]]
[[More than story telling]]
<!--{{{-->
<div class='header' DISABLED_macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='siteNav' class='siteNav' refresh='content' force='true' tiddler='SiteNav'></div>
<div id='breadCrumbs' class='breadCrumbs' style='font-size:80%;padding:0 1em;'></div>
<div id='mainMenu'
<div refresh='content' force='true' tiddler='MainMenu'></div>
<div refresh='content' force='true' tiddler='PoweredByTiddlyBlog' class='center tiny'></div>
</div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea' ondblclick='clearMessage()'></div>
<div id='storyMenu' refresh='content' force='true' tiddler='StoryMenu'></div>
<div id='tiddlerDisplay'></div>
<div style="position:fixed;z-index:1001;bottom:.3em;right:.3em;cursor:pointer;font-size:9pt;">
<a href="javascript:window.scrollTo(0,0)" title="scroll to top of page">▲</a>
</div>
</div>
<!--}}}-->
data://image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCACAAIABAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/APcgQtDuMYBqMKTz2ox82O1O2A84pSNuMU8Ht2oOO1IeOtRg847U8c9OlBGDilGDkYpU447Urcmo8fNmozkmjb82CamzgYpO9BbApM0quOlKTignIpoAzmlJxSFsc0BwfrTgeKMmkJAo7cUx1zzSqMDBNOHWlOPxpO1M43Cn5yM0UDk80rKKYQMUmw5GKlAwOaQkGmbRmm+bzjBxQzZpVU5yalxgcUnXk0U3aPSlxjHpTgOtIRjmlCluaa3ApBnFO3EUm3PJpuQDg0xiAcZoGRUg3dSKf703HNKFNP2HqaYf0pytgYpSwximAnn0pO9KBjmnqoxk0jKQPamMoIqArls1Kh6DFTBh0IpxIxQNrdqcAKWmEKaaUI6U32NLnAxTDgd6UMOlPD4U0w7iOtRMGz1qVYc07yzRtI4pduBQue1PJA61E8lM3n8KnU5Uc0yQfnTMkA5puMtT1TNSbR6Uu0VE0ZqcnAprNikEg70MwbpTMkdKaWY9aTbnrTMkHkVIHO3pSb/WnKNxp/lnPtRgp9KepDCncUUGoT1o25oGelIVz0p3l0m3nFBiyKRYiKeYgaEj2mpKRhkYpoTBzmn0Uxmx9ajLZo3A0EkcikByaeDT1xjiloAxRS0GkJwM0A5GaWjNRsuTmoyKTGKUk4piAs1WNg4o2kdDS8ik3ilVs06mlgKaxzxQGIGKeCDSZHrUZemO3cU0k59qmAXZTQAOlSBs/WnUxs55poA9aeoIpWOBSbgacMUxsZ4pgJJp+2lZMnIqJ+OgpoGVpRmlBIPFSKCeTT6jfk0nIFKGI60jMWpM0ocA0ZyaUACnL6GjOBn1qNsHimEFeaUc80o+9T1elLe9NL5p28Y6Uh5X3pApNIenFNxjnvRnv3pwYdTT1I6mm7j2pm7mnZ3Dik7YpM4pCe9KSaWkzTgc0pfB9qaXU8d6SmfzpwbPBp4wBThjOBTWXBqLeF4FIXJpFPOTUmAw4pRxSn1pKQNnpQ2evakUA89KUgjvxSFCeRQFIwTT1K5wa//Z
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
/***
|Name|PlayerPlugin|
|Source|http://www.TiddlyTools.com/#PlayerPlugin|
|Version|1.1.4|
|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|Embed a media player in a tiddler|
!!!!!Usage
<<<
{{{<<player [id=xxx] [type] [URL] [width] [height] [autoplay|true|false] [showcontrols|true|false] [extras]>>}}}
''id=xxx'' is optional, and specifies a unique identifier for each embedded player. note: this is required if you intend to display more than one player at the same time.
''type'' is optional, and is one of the following: ''windows'', ''realone'', ''quicktime'', ''flash'', ''image'' or ''iframe''. If the media type is not specified, the plugin automatically detects Windows, Real, QuickTime, Flash video or JPG/GIF images by matching known file extensions and/or specialized streaming-media transfer protocols (such as RTSP:). For unrecognized media types, the plugin displays an error message.
''URL'' is the location of the media content
''width'' and ''height'' are the dimensions of the video display area (in pixels)
''autoplay'' or ''true'' or ''false'' is optional, and specifies whether the media content should begin playing as soon as it is loaded, or wait for the user to press the "play" button. Default is //not// to autoplay.
''showcontrols'' or ''true'' or ''false'' is optional, and specifies whether the embedded media player should display its built-in control panel (e.g., play, pause, stop, rewind, etc), if any. Default is to display the player controls.
''extras'' are optional //pairs// of parameters that can be passed to the embedded player, using the {{{<param name=xxx value=yyy>}}} HTML syntax.
''If you use [[AttachFilePlugin]] to encode and store a media file within your document, you can play embedded media content by using the title of the //attachment tiddler//'' as a parameter in place of the usual reference to an external URL. When playing an attached media content, you should always explicitly specify the media type parameter, because the name used for the attachment tiddler may not contain a known file extension from which a default media type can be readily determined.
<<<
!!!!!Configuration
<<<
Default player size:
width: <<option txtPlayerDefaultWidth>> height: <<option txtPlayerDefaultHeight>>
<<<
!!!!!Examples
<<<
+++[Windows Media]...
Times Square Live Webcam
{{{<<player id=1 http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx>>}}}
<<player id=1 http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx>>
===
+++[RealOne]...
BBC London: Live and Recorded news
{{{<<player id=2 http://www.bbc.co.uk/london/realmedia/news/tvnews.ram>>}}}
<<player id=2 http://www.bbc.co.uk/london/realmedia/news/tvnews.ram>>
===
+++[Quicktime]...
America Free TV: Classic Comedy
{{{<<player id=3 http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov>>}}}
<<player id=3 http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov>>
===
+++[Flash]...
Asteroids arcade game
{{{<<player id=4 http://www.80smusiclyrics.com/games/asteroids/asteroids.swf 400 300>>}}}
<<player id=4 http://www.80smusiclyrics.com/games/asteroids/asteroids.swf 400 300>>
Google Video
{{{<<player id=5 flash http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DoQAAAIVnUNP6GYRY8YnIRNPe4Uk5-j1q1MVpJIW4uyEFpq5Si0hcSDuig_JZcB9nNpAhbScm9W_8y_vDJQBw1DRdCVbXl-wwm5dyUiiStl_rXt0ATlstVzrUNC4fkgK_j7nmse7kxojRj1M3eo3jXKm2V8pQjWk97GcksMFFwg7BRAXmRSERexR210Amar5LYzlo9_k2AGUWPLyRhMJS4v5KtDSvNK0neL83ZjlHlSECYXyk%26sigh%3Dmpt2EOr86OAUNnPQ3b9Tr0wnDms%26begin%3D0%26len%3D429700%26docid%3D-914679554478687740&thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer%3Fcontentid%3De7e77162deb04c42%26second%3D5%26itag%3Dw320%26urlcreated%3D1144620753%26sigh%3DC3fqXPPS1tFiUqLzmkX3pdgYc2Y&playerId=-91467955447868774 400 326>>}}}
<<player id=5 flash http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DoQAAAIVnUNP6GYRY8YnIRNPe4Uk5-j1q1MVpJIW4uyEFpq5Si0hcSDuig_JZcB9nNpAhbScm9W_8y_vDJQBw1DRdCVbXl-wwm5dyUiiStl_rXt0ATlstVzrUNC4fkgK_j7nmse7kxojRj1M3eo3jXKm2V8pQjWk97GcksMFFwg7BRAXmRSERexR210Amar5LYzlo9_k2AGUWPLyRhMJS4v5KtDSvNK0neL83ZjlHlSECYXyk%26sigh%3Dmpt2EOr86OAUNnPQ3b9Tr0wnDms%26begin%3D0%26len%3D429700%26docid%3D-914679554478687740&thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer%3Fcontentid%3De7e77162deb04c42%26second%3D5%26itag%3Dw320%26urlcreated%3D1144620753%26sigh%3DC3fqXPPS1tFiUqLzmkX3pdgYc2Y&playerId=-91467955447868774 400 326>>
YouTube Video
{{{<<player id=6 flash http://www.youtube.com/v/OdT9z-JjtJk 400 300>>}}}
<<player id=6 flash http://www.youtube.com/v/OdT9z-JjtJk 400 300>>
===
+++[Still Images]...
GIF (best for illustrations, animations, diagrams, etc.)
{{{<<player id=7 image images/meow.gif auto auto>>}}}
<<player id=7 image images/meow.gif auto auto>>
JPG (best for photographs, scanned images, etc.)
{{{<<player id=8 image images/meow2.jpg 200 150>>}}}
<<player id=8 image images/meow2.jpg 200 150>>
===
<<<
!!!!!Revisions
<<<
2008.05.10 [1.1.4] in handlers(), immediately return if no params (prevents error in macro). Also, refactored auto-detect code to make type mapping configurable.
2007.10.15 [1.1.3] in loadURL(), add recognition for .PNG (still image), fallback to iframe for unrecognized media types
2007.08.31 [1.1.2] added 'click-through' link for JPG/GIF images
2007.06.21 [1.1.1] changed "hidecontrols" param to "showcontrols" and recognize true/false values in addition to 'showcontrols', added "autoplay" param (also recognize true/false values), allow "auto" as value for type param
2007.05.22 [1.1.0] added support for type=="iframe" (displays src URL in an IFRAME)
2006.12.06 [1.0.1] in handler(), corrected check for config.macros.attach (instead of config.macros.attach.getAttachment) so that player plugin will work when AttachFilePlugin is NOT installed. (Thanks to Phillip Ehses for bug report)
2006.11.30 [1.0.0] support embedded media content using getAttachment() API defined by AttachFilePlugin or AttachFilePluginFormatters. Also added support for 'image' type to render JPG/GIF still images
2006.02.26 [0.7.0] major re-write. handles default params better. create/recreate player objects via loadURL() API for use with interactive forms and scripts.
2006.01.27 [0.6.0] added support for 'extra' macro params to pass through to object parameters
2006.01.19 [0.5.0] Initial ALPHA release
2005.12.23 [0.0.0] Started
<<<
!!!!!Code
***/
//{{{
version.extensions.PlayerPlugin= {major: 1, minor: 1, revision: 4, date: new Date(2008,5,10)};
config.macros.player = {};
config.macros.player.html = {};
config.macros.player.handler= function(place,macroName,params) {
if (!params.length) return; // missing parameters - do nothing
var id=null;
if (params[0].substr(0,3)=="id=") id=params.shift().substr(3);
var type="";
if (!params.length) return; // missing parameters - do nothing
var p=params[0].toLowerCase();
if (p=="auto" || p=="windows" || p=="realone" || p=="quicktime" || p=="flash" || p=="image" || p=="iframe")
type=params.shift().toLowerCase();
var url=params.shift(); if (!url || !url.trim().length) url="";
if (url.length && config.macros.attach!=undefined) // if AttachFilePlugin is installed
if ((tid=store.getTiddler(url))!=null && tid.isTagged("attachment")) // if URL is attachment
url=config.macros.attach.getAttachment(url); // replace TiddlerTitle with URL
var width=params.shift();
var height=params.shift();
var autoplay=false;
if (params[0]=='autoplay'||params[0]=='true'||params[0]=='false')
autoplay=(params.shift()!='false');
var show=true;
if (params[0]=='showcontrols'||params[0]=='true'||params[0]=='false')
show=(params.shift()!='false');
var extras="";
while (params[0]!=undefined)
extras+="<param name='"+params.shift()+"' value='"+params.shift()+"'> ";
this.loadURL(place,id,type,url,width,height,autoplay,show,extras);
}
if (config.options.txtPlayerDefaultWidth==undefined) config.options.txtPlayerDefaultWidth="100%";
if (config.options.txtPlayerDefaultHeight==undefined) config.options.txtPlayerDefaultHeight="480"; // can't use "100%"... player height doesn't stretch right :-(
config.macros.player.typeMap={
windows: ['mms', '.asx', '.wvx', '.wmv', '.mp3'],
realone: ['rtsp', '.ram', '.rpm', '.rm', '.ra'],
quicktime: ['.mov', '.qt'],
flash: ['.swf', '.flv'],
image: ['.jpg', '.gif', '.png'],
iframe: ['.htm', '.html', '.shtml', '.php']
};
config.macros.player.loadURL=function(place,id,type,url,width,height,autoplay,show,extras) {
if (id==undefined) id="tiddlyPlayer";
if (!width) var width=config.options.txtPlayerDefaultWidth;
if (!height) var height=config.options.txtPlayerDefaultHeight;
if (url && (!type || !type.length || type=="auto")) { // determine type from URL
u=url.toLowerCase();
var map=config.macros.player.typeMap;
for (var t in map) for (var i=0; i<map[t].length; i++)
if (u.indexOf(map[t][i])!=-1) var type=t;
}
if (!type || !config.macros.player.html[type]) var type="none";
if (!url) var url="";
if (show===undefined) var show=true;
if (!extras) var extras="";
if (type=="none" && url.trim().length) type="iframe"; // fallback to iframe for unrecognized media types
// adjust parameter values for player-specific embedded HTML
switch (type) {
case "windows":
autoplay=autoplay?"1":"0"; // player-specific param value
show=show?"1":"0"; // player-specific param value
break;
case "realone":
autoplay=autoplay?"true":"false";
show=show?"block":"none";
height-=show?60:0; // leave room for controls
break;
case "quicktime":
autoplay=autoplay?"true":"false";
show=show?"true":"false";
break;
case "image":
show=show?"block":"none";
break;
case "iframe":
show=show?"block":"none";
break;
}
// create containing div for player HTML
// and add or replace player in TW DOM structure
var newplayer = document.createElement("div");
newplayer.playerType=type;
newplayer.setAttribute("id",id+"_div");
var existing = document.getElementById(id+"_div");
if (existing && !place) place=existing.parentNode;
if (!existing)
place.appendChild(newplayer);
else {
if (place==existing.parentNode) place.replaceChild(newplayer,existing)
else { existing.parentNode.removeChild(existing); place.appendChild(newplayer); }
}
var html=config.macros.player.html[type];
html=html.replace(/%i%/mg,id);
html=html.replace(/%w%/mg,width);
html=html.replace(/%h%/mg,height);
html=html.replace(/%u%/mg,url);
html=html.replace(/%a%/mg,autoplay);
html=html.replace(/%s%/mg,show);
html=html.replace(/%x%/mg,extras);
newplayer.innerHTML=html;
}
//}}}
// // Player-specific API functions: isReady(id), isPlaying(id), toggleControls(id), showControls(id,flag)
//{{{
// status values:
// Windows: 0=Undefined, 1=Stopped, 2=Paused, 3=Playing, 4=ScanForward, 5=ScanReverse
// 6=Buffering, 7=Waiting, 8=MediaEnded, 9=Transitioning, 10=Ready, 11=Reconnecting
// RealOne: 0=Stopped, 1=Contacting, 2=Buffering, 3=Playing, 4=Paused, 5=Seeking
// QuickTime: 'Waiting', 'Loading', 'Playable', 'Complete', 'Error:###'
// Flash: 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete
config.macros.player.isReady=function(id)
{
var d=document.getElementById(id+"_div"); if (!d) return false;
var p=document.getElementById(id); if (!p) return false;
if (d.playerType=='windows') return !((p.playState==0)||(p.playState==7)||(p.playState==9)||(p.playState==11));
if (d.playerType=='realone') return (p.GetPlayState()>1);
if (d.playerType=='quicktime') return !((p.getPluginStatus()=='Waiting')||(p.getPluginStatus()=='Loading'));
if (d.playerType=='flash') return (p.ReadyState>2);
return true;
}
config.macros.player.isPlaying=function(id)
{
var d=document.getElementById(id+"_div"); if (!d) return false;
var p=document.getElementById(id); if (!p) return false;
if (d.playerType=='windows') return (p.playState==3);
if (d.playerType=='realone') return (p.GetPlayState()==3);
if (d.playerType=='quicktime') return (p.getPluginStatus()=='Complete');
if (d.playerType=='flash') return (p.ReadyState<4);
return false;
}
config.macros.player.showControls=function(id,flag) {
var d=document.getElementById(id+"_div"); if (!d) return false;
var p=document.getElementById(id); if (!p) return false;
if (d.playerType=='windows') { p.ShowControls=flag; p.ShowStatusBar=flag; }
if (d.playerType=='realone') { alert('show/hide controls not available'); }
if (d.playerType=='quicktime') // if player not ready, retry in one second
{ if (this.isReady(id)) p.setControllerVisible(flag); else setTimeout('config.macros.player.showControls("'+id+'",'+flag+')',1000); }
if (d.playerType=='flash') { alert('show/hide controls not available'); }
}
config.macros.player.toggleControls=function(id) {
var d=document.getElementById(id+"_div"); if (!d) return false;
var p=document.getElementById(id); if (!p) return false;
if (d.playerType=='windows') var flag=!p.ShowControls;
if (d.playerType=='realone') var flag=true; // TBD
if (d.playerType=='quicktime') var flag=!p.getControllerVisible();
if (d.playerType=='flash') var flag=true; // TBD
this.showControls(id,flag);
}
config.macros.player.fullScreen=function(id) {
var d=document.getElementById(id+"_div"); if (!d) return false;
var p=document.getElementById(id); if (!p) return false;
if (d.playerType=='windows') p.DisplaySize=3;
if (d.playerType=='realone') p.SetFullScreen();
if (d.playerType=='quicktime') { alert('full screen not available'); }
if (d.playerType=='flash') { alert('full screen not available'); }
}
//}}}
// // Player HTML
//{{{
// placeholder (no player)
config.macros.player.html.none=' \
<table id="%i%" width="%w%" height="%h%" style="background-color:#111;border:0;margin:0;padding:0;"> \
<tr style="background-color:#111;border:0;margin:0;padding:0;"> \
<td width="%w%" height="%h%" style="background-color:#111;color:#ccc;border:0;margin:0;padding:0;text-align:center;"> \
\
%u% \
\
</td></tr></table>';
//}}}
//{{{
// JPG/GIF/PNG still images
config.macros.player.html.image='\
<a href="%u%" target="_blank"><img width="%w%" height="%h%" style="display:%s%;" src="%u%"></a>';
//}}}
//{{{
// IFRAME web page viewer
config.macros.player.html.iframe='\
<iframe id="%i%" width="%w%" height="%h%" style="display:%s%;background:#fff;" src="%u%"></iframe>';
//}}}
//{{{
// Windows Media Player
// v7.1 ID: classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6
// v9 ID: classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95
config.macros.player.html.windows=' \
<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" \
codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" \
align="baseline" border="0" \
standby="Loading Microsoft Windows Media Player components..." \
type="application/x-oleobject"> \
<param name="FileName" value="%u%"> <param name="ShowControls" value="%s%"> \
<param name="ShowPositionControls" value="1"> <param name="ShowAudioControls" value="1"> \
<param name="ShowTracker" value="1"> <param name="ShowDisplay" value="0"> \
<param name="ShowStatusBar" value="1"> <param name="AutoSize" value="1"> \
<param name="ShowGotoBar" value="0"> <param name="ShowCaptioning" value="0"> \
<param name="AutoStart" value="%a%"> <param name="AnimationAtStart" value="1"> \
<param name="TransparentAtStart" value="0"> <param name="AllowScan" value="1"> \
<param name="EnableContextMenu" value="1"> <param name="ClickToPlay" value="1"> \
<param name="InvokeURLs" value="1"> <param name="DefaultFrame" value="datawindow"> \
%x% \
<embed src="%u%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
align="baseline" border="0" width="%w%" height="%h%" \
type="application/x-mplayer2" \
pluginspage="http://www.microsoft.com/windows/windowsmedia/download/default.asp" \
name="%i%" showcontrols="%s%" showpositioncontrols="1" \
showaudiocontrols="1" showtracker="1" showdisplay="0" \
showstatusbar="%s%" autosize="1" showgotobar="0" showcaptioning="0" \
autostart="%a%" autorewind="0" animationatstart="1" transparentatstart="0" \
allowscan="1" enablecontextmenu="1" clicktoplay="0" invokeurls="1" \
defaultframe="datawindow"> \
</embed> \
</object>';
//}}}
//{{{
// RealNetworks' RealOne Player
config.macros.player.html.realone=' \
<table width="%w%" style="border:0;margin:0;padding:0;"><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \
<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
<PARAM NAME="CONSOLE" VALUE="player"> \
<PARAM NAME="CONTROLS" VALUE="ImageWindow"> \
<PARAM NAME="AUTOSTART" Value="%a%"> \
<PARAM NAME="MAINTAINASPECT" Value="true"> \
<PARAM NAME="NOLOGO" Value="true"> \
<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
<PARAM NAME="SRC" VALUE="%u%"> \
%x% \
<EMBED width="%w%" height="%h%" controls="ImageWindow" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;" \
name="%i%" \
src="%u%" \
console=player \
maintainaspect=true \
nologo=true \
backgroundcolor=#333333 \
autostart=%a%> \
</OBJECT> \
</td></tr><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \
<object id="%i%_controls" width="%w%" height="60" style="margin:0;padding:0;display:%s%" \
CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
<PARAM NAME="CONSOLE" VALUE="player"> \
<PARAM NAME="CONTROLS" VALUE="All"> \
<PARAM NAME="NOJAVA" Value="true"> \
<PARAM NAME="MAINTAINASPECT" Value="true"> \
<PARAM NAME="NOLOGO" Value="true"> \
<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
<PARAM NAME="SRC" VALUE="%u%"> \
%x% \
<EMBED WIDTH="%w%" HEIGHT="60" NOJAVA="true" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;display:%s%" \
controls="All" \
name="%i%_controls" \
src="%u%" \
console=player \
maintainaspect=true \
nologo=true \
backgroundcolor=#333333> \
</OBJECT> \
</td></tr></table>';
//}}}
//{{{
// QuickTime Player
config.macros.player.html.quicktime=' \
<OBJECT ID="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" \
CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab"> \
<PARAM name="SRC" VALUE="%u%"> \
<PARAM name="AUTOPLAY" VALUE="%a%"> \
<PARAM name="CONTROLLER" VALUE="%s%"> \
<PARAM name="BGCOLOR" VALUE="#333333"> \
<PARAM name="SCALE" VALUE="aspect"> \
<PARAM name="SAVEEMBEDTAGS" VALUE="true"> \
%x% \
<EMBED name="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
SRC="%u%" \
AUTOPLAY="%a%" \
SCALE="aspect" \
CONTROLLER="%s%" \
BGCOLOR="#333333" \
EnableJavaSript="true" \
PLUGINSPAGE="http://www.apple.com/quicktime/download/"> \
</EMBED> \
</OBJECT>';
//}}}
//{{{
// Flash Player
config.macros.player.html.flash='\
<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" \
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0"> \
<param name="movie" value="%u%"> \
<param name="quality" value="high"> \
<param name="SCALE" value="exactfit"> \
<param name="bgcolor" value="333333"> \
%x% \
<embed name="%i%" src="%u%" style="margin:0;padding:0;" \
height="%h%" width="%w%" quality="high" \
pluginspage="http://www.macromedia.com/go/getflashplayer" \
type="application/x-shockwave-flash" scale="exactfit"> \
</embed> \
</object>';
//}}}
[[ZenMaker]]
[[EyeCandy]]
This package provides a toolbar of interactive 'power tools' that you can use while editing a tiddler to quickly insert TiddlyWiki tiddler links, images, macros, etc. or common formatting sequences directly into tiddler content, as well as perform other functions (such as find/replace, sort, split, convert, etc.) that can be used to modify the current tiddler's source content in a variety of ways.
<<tiddler QuickEditToolbar with: show>>
!!!!!Installation:
<<<
Individual ~QuickEdit buttons are defined in separate tiddlers (e.g., [[QuickEdit_replace]]) that have also been //transcluded// into a single toolbar definition named [[QuickEditToolbar]]. You can edit this definition to add, remove, or rearrange the toolbar buttons to best suit your needs, and then embed the [[QuickEditToolbar]] tiddler into your document's [[EditTemplate]], like this:
{{{
<div macro='tiddler QuickEditToolbar'></div>
}}}
Next, in order to support some of the formatting 'shortcuts' provided by the toolbar, add a reference to the shortcuts CSS class definitions in your [[StyleSheet]]:
{{{
[[StyleSheetShortcuts]]
}}}
By default, the QuickEdit toolbar is hidden until you enable it by using the ''toggleQuickEdit'' command, which you can add to the ~EditToolbar definition in [[ToolbarCommands]]:
{{{
|EditToolbar|... toggleQuickEdit ...|
}}}
You can also toggle the ~QuickEdit toolbar display via a single checkbox option that can be added to [[SideBarOptions]] (or any other desired location):
{{{
<<option chkShowQuickEdit>> show QuickEdit toolbar
}}}
Note: You can 'hard-code' the ''chkShowQuickEdit'' setting, so that the toolbar will be //initially// displayed, by creating a tiddler (e.g., ConfigTweaks), tagged with <<tag systemConfig>>, containing:
{{{
config.options.chkShowQuickEdit=true;
}}}
Alternatively, if you want the toolbar to //always// be displayed, regardless of the option setting, you can add a special keyword, ''show'', to the [[EditTemplate]] syntax, like this:
{{{
<div macro='tiddler QuickEditToolbar with: show'></div>
}}}
<<<
/***
|Name|QuickEditPlugin|
|Source|http://www.TiddlyTools.com/#QuickEditPlugin|
|Documentation|http://www.TiddlyTools.com/#QuickEditPlugin|
|Version|2.4.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Support functions for ~QuickEdit package: styles, utility functions, and 'toggleQuickEdit' command|
!!!!!Revisions
<<<
2008.09.07 [2.4.1] added removeCookie() function for compatibility with [[CookieManagerPlugin]]
2008.05.17 [2.4.0] copied code from StickyPopupPlugin to remove dependency
2008.05.12 [2.3.0] added "toggleQuickEdit" command handler (replaces inline script command)
2008.01.11 [2.2.0] converted from inline script
2007.03.29 [1.0.0] initial release (as inline script)
<<<
!!!!!Code
***/
//{{{
version.extensions.QuickEditPlugin= {major: 2, minor: 4, revision: 1, date: new Date(2008,9,7)};
// SET STYLESHEET (for toolbar button style)
setStylesheet("\
.quickEdit a { border:2px outset ButtonFace; padding:0px 3px !important; \
-moz-border-radius:.5em; -webkit-border-radius:.5em; \
-moz-appearance:button !important; -webkit-appearance:push-button !important; \
background-color:ButtonFace; color:ButtonText !important; \
line-height:200%; font-weight:normal; } \
.quickEdit a:hover { border: 2px inset ButtonFace; background-color:ButtonFace; }\
", "quickEditStyles");
// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
window.removeCookie=function(name) {
document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
}
}
// UTILITY FUNCTIONS
config.quickEdit = {
getField: function(where) {
var here=story.findContainingTiddler(where); if (!here) return null;
var e=story.getTiddlerField(here.getAttribute("tiddler"),"text");
if (e&&e.getAttribute("edit")=="text") return e;
return null;
},
setSelection: function(where,newtext) {
var e=this.getField(where); if (!e) return false;
e.focus(); replaceSelection(e,newtext);
return false;
},
wrapSelection: function(where,before,after) {
var e=this.getField(where); if (!e) return false;
e.focus(); replaceSelection(e,before+config.quickEdit.getSelection(e)+after);
return false;
},
getSelection: function(e) {
var seltext="";
if (e&&e.setSelectionRange)
seltext=e.value.substr(e.selectionStart,e.selectionEnd-e.selectionStart);
else if (document.selection) {
var range = document.selection.createRange();
if (range.parentElement()==e) seltext=range.text
}
return seltext;
},
promptForFilename: function(msg,path,file) {
if(window.Components) { // moz
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, nsIFilePicker.modeOpen);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='jpg';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterImages);
if (picker.show()!=nsIFilePicker.returnCancel)
var result="file:///"+picker.file.persistentDescriptor.replace(/\\/g,'/');
}
catch(e) { alert('error during local file access: '+e.toString()) }
}
else { // IE
try { // XP only
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|JPG files|*.jpg|GIF files|*.gif|PNG files|*.png|';
s.FilterIndex=1; // default to JPG files;
s.InitialDir=path;
s.FileName=file;
if (s.showOpen()) var result=s.FileName;
}
catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
}
return result;
}
}
//}}}
//{{{
if (config.options.chkShowQuickEdit===undefined) config.options.chkShowQuickEdit=false;
config.commands.toggleQuickEdit = {
hideReadOnly: true,
getText: function() { return config.options.chkShowQuickEdit?'\u221Aquickedit':'quickedit'; },
tooltip: 'show QuickEdit toolbar buttons',
handler: function(event,src,title) {
config.options.chkShowQuickEdit=!config.options.chkShowQuickEdit;
config.macros.option.propagateOption("chkShowQuickEdit","checked", config.options.chkShowQuickEdit,"input");
// save cookie when toolbar shown, remove cookie when toolbar hidden
if (config.options.chkShowQuickEdit) saveOptionCookie("chkShowQuickEdit");
else removeCookie("chkShowQuickEdit");
// set link and title based on option state
src.innerHTML=config.commands.toggleQuickEdit.getText();
// refresh all actively displayed tiddler editor(s)
story.forEachTiddler(function(t,e){if (story.isDirty(t)) refreshElements(e);});
return false;
}
};
//}}}
// // COPIED FROM [[StickyPopupPlugin]] TO ELIMINATE PLUGIN DEPENDENCY
//{{{
if (config.options.chkStickyPopups==undefined) config.options.chkStickyPopups=false;
Popup.stickyPopup_onDocumentClick = function(ev)
{
// if click is in a sticky popup, ignore it so popup will remain visible
var e = ev ? ev : window.event; var target = resolveTarget(e);
var p=target; while (p) {
if (hasClass(p,"popup") && (hasClass(p,"sticky")||config.options.chkStickyPopups)) break;
else p=p.parentNode;
}
if (!p) // not in sticky popup (or sticky popups disabled)... use normal click handling
Popup.onDocumentClick(ev);
return true;
};
try{removeEvent(document,"click",Popup.onDocumentClick);}catch(e){};
try{addEvent(document,"click",Popup.stickyPopup_onDocumentClick);}catch(e){};
//}}}
/%
|Name|QuickEditToolbar|
|Source|http://www.TiddlyTools.com/#QuickEditToolbar|
|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.2|
|Type|script|
|Requires|QuickEditPlugin, InlineJavascriptPlugin|
|Optional|QuickEdit_replace, QuickEdit_split, QuickEdit_link, QuickEdit_macro, QuickEdit_image, QuickEdit_tiddler, QuickEdit_file, QuickEdit_format, QuickEdit_sort|
|Overrides||
|Description|quickly insert TiddlyWiki tiddler links or common formatting sequences directly into tiddler content|
Usage (in EditTemplate): <div macro='tiddler QuickEditToolbar with: show'></div>
where "show" is an OPTIONAL keyword to force the toolbar to be displayed regardless of the current 'toggle' state
%/<<tiddler HideTiddlerTags>>/%
TOOLBAR DEFINITIONS BEGIN HERE...
= = = = = = = = = = = = = = = = =
%/{{hidden fine center quickEdit{
<script>
// note: always show toolbar when directly viewing the tiddler containing the actual toolbar definition!
var here=story.findContainingTiddler(place); if (here) var tid=here.getAttribute("tiddler");
var show="$1"!="$"+"1"||config.options.chkShowQuickEdit||tid=="QuickEditToolbar"
place.style.display=show?"block":"none";
</script>/%
%/<<tiddler QuickEdit_replace>>/%
%/<<tiddler QuickEdit_split>>/%
%/<<tiddler QuickEdit_sort>>/%
%/<<tiddler QuickEdit_convert>>/%
%/ /% (SPACER)
%/<<tiddler QuickEdit_link>>/%
%/<<tiddler QuickEdit_macro>>/%
%/<<tiddler QuickEdit_image>>/%
%/<<tiddler QuickEdit_tiddler>>/%
%/<<tiddler QuickEdit_file>>/%
%/ /% (SPACER)
%/<<tiddler QuickEdit_format>>/%
%/<<tiddler QuickEdit_align>>/%
%/<<tiddler QuickEdit_color>>/%
%/<<tiddler QuickEdit_font>>/%
%/<<tiddler QuickEdit_custom>>/%
%/}}}
/%
|Name|QuickEdit_align|
|Source|http://www.TiddlyTools.com/#QuickEdit_align|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button for text alignment|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_align>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_align'></span>
**** ALIGNMENT ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="align text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select text alignment...','');
s.onchange=function(){
config.quickEdit.wrapSelection(this.button,'{{'+this.value+'{','}}}');
Popup.remove(); return false;
};
s.options[s.length]=new Option('left','left');
s.options[s.length-1].title='{{left{...}}}';
s.options[s.length]=new Option('center','center');
s.options[s.length-1].title='{{center{...}}}';
s.options[s.length]=new Option('right','right');
s.options[s.length-1].title='{{right{...}}}';
s.options[s.length]=new Option('justify','justify');
s.options[s.length-1].title='{{justify{...}}}';
s.options[s.length]=new Option('float left','floatleft');
s.options[s.length-1].title='{{floatleft{...}}}';
s.options[s.length]=new Option('float right','floatright');
s.options[s.length-1].title='{{floatright{...}}}';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>align</a></html>
/%
|Name|QuickEdit_color|
|Source|http://www.TiddlyTools.com/#QuickEdit_color|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition of toolbar button for "color" command|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_color>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_color'></span>
**** COLOR ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="text/background color - @@color:#RGB;background-color:#RGB;...@@"
onclick="var p=Popup.create(this,null,'popup sticky smallform'); if (!p) return false;
p.style.padding='2px';
function hex(d) { return '0123456789ABCDEF'.substr(d,1); }
var fg=createTiddlyElement(p,'select'); fg.button=this;
fg.style.width='12em';
fg.options[0]=new Option('text color...','');
fg.options[1]=new Option('\xa0 or enter a value','_ask');
fg.options[2]=new Option('\xa0 or use default color','');
for (var r=0;r<16;r+=3) for (var g=0;g<16;g+=3) for (var b=0;b<16;b+=3) {
var label=hex(r)+hex(g)+hex(b);
fg.options[fg.length]=new Option(label,'#'+label);
fg.options[fg.length-1].style.color='#'+label;
}
fg.onchange=function(){ var val=this.value;
if (val=='_ask') { val=prompt('Enter a CSS color value');
if (!val||!val.length) return false; }
this.options[0].value=val; this.options[0].text=val.length?'text: '+val:'text color...';
var bg=this.nextSibling;
for (var i=3;i<bg.options.length;i++) bg.options[i].style.color=val;
var preview=this.nextSibling.nextSibling.nextSibling;
var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
if (!t.length) t='~AaBbCcDdEeFfGgHhIiJj 1234567890';
var fg=this.value; if (fg.length) fg='color:'+fg+';';
var bg=this.nextSibling.value; if (bg.length) bg='background-color:'+bg+';';
if (fg.length||bg.length) t='@@'+fg+bg+t+'@@';
removeChildren(preview); wikify(t,preview);
this.selectedIndex=0; return false;
};
var bg=createTiddlyElement(p,'select'); bg.button=this;
bg.style.width='12em';
bg.options[0]=new Option('background color...','');
bg.options[1]=new Option('\xa0 or enter a value','_ask');
bg.options[2]=new Option('\xa0 or use default color','');
for (var r=0;r<16;r+=3) for (var g=0;g<16;g+=3) for (var b=0;b<16;b+=3) {
var label=hex(15-r)+hex(15-g)+hex(15-b);
bg.options[bg.length]=new Option(label,'#'+label);
bg.options[bg.length-1].style.backgroundColor='#'+label;
}
bg.onchange=function(){ var val=this.value;
if (val=='_ask') { val=prompt('Enter a CSS color value');
if (!val||!val.length) return false; }
this.options[0].value=val;
this.options[0].text=val.length?'background: '+val:'background color...';
var fg=this.previousSibling;
for (var i=3;i<fg.options.length;i++) fg.options[i].style.backgroundColor=val;
var preview=this.nextSibling.nextSibling;
var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
if (!t.length) t='~AaBbCcDdEeFfGgHhIiJj 1234567890';
var fg=this.previousSibling.value; if (fg.length) fg='color:'+fg+';';
var bg=this.value; if (bg.length) bg='background-color:'+bg+';';
if (fg.length||bg.length) t='@@'+fg+bg+t+'@@';
removeChildren(preview); wikify(t,preview);
this.selectedIndex=0; return false;
};
var b=createTiddlyElement(p,'input',null,null,null,{type:'button'}); b.button=this;
b.value='ok'; b.style.width='4em';
b.onclick=function() {
var fg=this.previousSibling.previousSibling.value; if (fg.length) fg='color:'+fg+';';
var bg=this.previousSibling.value; if (bg.length) bg='background-color:'+bg+';';
var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
if (fg.length||bg.length) config.quickEdit.setSelection(this.button,'@@'+fg+bg+t+'@@');
Popup.remove(); return false;
};
var preview=createTiddlyElement(p,'div',null,'viewer'); var s=preview.style;
s.border='1px solid'; s.margin='2px'; s.width='24em'; s.padding='3px'; s.MozBorderRadius='3px';
s.overflow='hidden'; s.textAlign='center'; s.whiteSpace='normal';
var t=config.quickEdit.getSelection(config.quickEdit.getField(this));
wikify(t.length?t:'~AaBbCcDdEeFfGgHhIiJj 1234567890',preview);
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>color</a></html>
/%
|Name|QuickEdit_convert|
|Source|http://www.TiddlyTools.com/#QuickEdit_convert|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|toolbar button for converting tab/comma-separated data to/from table format|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_convert>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_convert'></span>
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="convert between tab-separated, comma-separated data and wiki table formats"
onclick="var e=config.quickEdit.getField(this);
if (e) e.focus(); var txt=config.quickEdit.getSelection(e);
var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.onchange=function(){
if (!this.value) return false;
var e=config.quickEdit.getField(this.button); if (!e) return false;
e.focus(); var txt=config.quickEdit.getSelection(e);
switch(this.value) {
case 'tabsToTable':
txt=txt.replace(/\t/g,'|').replace(/^|$/g,'|');
txt=txt.replace(/\n/g,'|\n|').replace(/^\|$/g,'');
break;
case 'tableToTabs':
txt=txt.replace(/\t/g,' ').replace(/\|/g,'\t');
txt=txt.replace(/^\t/g,'').replace(/\t$/g,'');
txt=txt.replace(/\n\t/g,'\n').replace(/\t\n/g,'\n');
break;
case 'commasToTable':
txt=txt.replace(/,/g,'|').replace(/^|$/g,'|');
txt=txt.replace(/\n/g,'|\n|').replace(/^\|$/g,'');
break;
case 'tableToCommas':
txt=txt.replace(/,/g,' ').replace(/\|/g,',');
txt=txt.replace(/^,/g,'').replace(/,$/g,'');
txt=txt.replace(/\n,/g,'\n').replace(/,\n/g,'\n');
break;
case 'tabsToCommas':
txt=txt.replace(/\t/g,',');
break;
case 'commasToTabs':
txt=txt.replace(/,/g,'\t');
break;
}
replaceSelection(e,txt);
Popup.remove(); return false;
};
s.options[0]=new Option('select a converter...','');
if (txt.indexOf(',')!=-1) {
s.options[s.length]=new Option('commas -> table','commasToTable');
s.options[s.length]=new Option('commas -> tabs','commasToTabs');
}
if (txt.indexOf('\t')!=-1) {
s.options[s.length]=new Option('tabs -> table','tabsToTable');
s.options[s.length]=new Option('tabs -> commas','tabsToCommas');
}
if (txt.indexOf('|')!=-1) {
s.options[s.length]=new Option('table -> tabs','tableToTabs');
s.options[s.length]=new Option('table -> commas','tableToCommas');
}
if (s.options.length==1) {
s.options[0]=new Option('select some text first...','');
if (txt.length) alert('There are no converters that can be applied, because the selected text does not contain any tabs, commas, or TiddlyWiki table syntax.');
}
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>convert</a></html>
/%
|Name|QuickEdit_custom|
|Source|http://www.TiddlyTools.com/#QuickEdit_custom|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|provides a droplist of custom-defined formats|
Usage:
in QuickEditToolbar: <<tiddler QuickEdit_custom>>
OR
in EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_custom'></span>
!help
Reminders:
Custom format definitions are stored as an "HR-separated list" in a tiddler named [[QuickEdit_customList]].
The first line of each list item is the text 'label' to show in the droplist, followed by one or more lines of wiki content to be inserted into the tiddler source.
To embed the tiddler editor's current selected text within the formatted output, use "$1" (without quotes) to mark the position(s) where the selection should be inserted.
!end help
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="custom defined formats"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select a custom format...','');
s.onchange=function(){
if (!this.value.length) return;
if (this.value=='_edit') {
alert(store.getTiddlerText('QuickEdit_custom##help'));
story.displayTiddler(story.findContainingTiddler(this.button),
'QuickEdit_customList',DEFAULT_EDIT_TEMPLATE);
} else {
var e=config.quickEdit.getField(this.button); if (!e) return false;
e.focus(); var txt=config.quickEdit.getSelection(e);
replaceSelection(e,this.value.replace(/\$\x31/g,txt));
}
Popup.remove(); return false;
};
var items=store.getTiddlerText('QuickEdit_customList','').split('\n----\n');
for (var i=0; i<items.length; i++) {
if (!items[i].length) continue; var lines=items[i].split('\n');
var label=lines.shift(); var val=lines.join('\n');
s.options[s.length]=new Option(label,val); s.options[s.length-1].title=val;
}
s.options[s.length]=new Option('[Edit custom formats...]','_edit');
s.options[s.length-1].title='add/change custom format definitions...';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>custom</a></html>
scrollbox
@@display:block;height:10em;overflow:auto;$1@@@@display:block;text-align:right;^^scroll for more...^^@@
----
nested slider
+++[$1]<<tiddler $1>>===
----
big red
@@font-size:36pt;color:red;$1@@
----
/%
|Name|QuickEdit_file|
|Source|http://www.TiddlyTools.com/#QuickEdit_file|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar buttons that insert content from external files|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_file>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_file'></span>
**** INSERT FILE ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="insert content from an external text file"
onclick="var fn=config.quickEdit.promptForFilename('Enter/select a text file',getLocalPath(document.location.href),'');
if (!fn) return false; /* cancelled by user */
var text=loadFile(getLocalPath(fn)); if (!text) { alert('Error: unable to read contents from \0027'+fn+'\0027'); return; }
return config.quickEdit.setSelection(place,text);"
>file</a></html>
/%
|Name|QuickEdit_font|
|Source|http://www.TiddlyTools.com/#QuickEdit_font|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button that set font-family CSS attribute|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_font>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_macro'></span>
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="set font-family CSS attribute - @@font-family:facename;...@@"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select a font family...','');
s.onchange=function(){
if (this.value=='_edit')
story.displayTiddler(story.findContainingTiddler(this.button),'QuickEdit_fontList',DEFAULT_EDIT_TEMPLATE);
else
config.quickEdit.wrapSelection(this.button,'@@font-family:\x22'+this.value+'\x22;','@@');
Popup.remove(); return false;
};
var fonts=store.getTiddlerText('QuickEdit_fontList','').split('\n');
for (var i=0; i<fonts.length; i++) {
if (!fonts[i].length) continue;
s.options[s.length]=new Option(fonts[i],fonts[i]);
s.options[s.length-1].style.fontFamily=fonts[i];
}
s.options[s.length]=new Option('[Edit font list...]','_edit');
s.options[s.length-1].title='enter fonts, one per line...';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>font</a></html>
Arial,helvetica,sans-serif
Times New Roman,times,serif
Courier,monospaced
/%
|Name|QuickEdit_format|
|Source|http://www.TiddlyTools.com/#QuickEdit_format|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button for text formatting|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_format>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_format'></span>
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" title="''bold''" accesskey="B"
onclick="config.quickEdit.wrapSelection(this,'\x27\x27','\x27\x27'); return false;"
> B </a></html>/%
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" title="//italics//" accesskey="I"
onclick="config.quickEdit.wrapSelection(this,'//','//'); return false;"
> I </a></html>/%
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" title="__underline__" accesskey="U"
onclick="config.quickEdit.wrapSelection(this,'__','__'); return false;"
> U </a></html>/%
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" title="--strikethrough--" accesskey="S"
onclick="config.quickEdit.wrapSelection(this,'--','--'); return false;"
> S </a></html>/%
%/ /% SPACER
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="format text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.onchange=function(){
var parts=this.value.split(',');
var prefix=parts[0]; var suffix=parts[1]; var ask=parts[2];
if (ask) {
var val=prompt(ask); if (!val) { Popup.remove(); return false; }
prefix=prefix.replace(/\$1/g,val); suffix=suffix.replace(/\$1/g,val);
}
config.quickEdit.wrapSelection(this.button,prefix,suffix);
Popup.remove(); return false;
};
s.options[0]=new Option('select text format...','');
s.options[s.length]=new Option('CSS class wrapper','{{$1{,}}},Enter a CSS classname');
s.options[s.length-1].title='CSS class wrapper - {{classname classname etc{...}}}';
s.options[s.length]=new Option('inline CSS styles','@@$1,@@,Enter CSS (attribute:value;attribute:value;...;)');
s.options[s.length-1].title='inline CSS styles - @@attr:value;attr:value;...@@';
s.options[s.length]=new Option('heading 1','\n!,\n');
s.options[s.length-1].title='H1 heading - !';
s.options[s.length]=new Option('heading 2','\n!!,\n');
s.options[s.length-1].title='H2 heading - !!';
s.options[s.length]=new Option('heading 3','\n!!!,\n');
s.options[s.length-1].title='H3 heading - !!!';
s.options[s.length]=new Option('heading 4','\n!!!!,\n');
s.options[s.length-1].title='H4 heading - !!!!';
s.options[s.length]=new Option('heading 5','\n!!!!!,\n');
s.options[s.length-1].title='H5 heading - !!!!!';
s.options[s.length]=new Option('blockquote','\n\<\<\<\n,\n\<\<\<\n');
s.options[s.length-1].title='indented blockquote - \<\<\<';
s.options[s.length]=new Option('monospaced','{{{,}}}');
s.options[s.length-1].title='inline monospaced text - {{{...}}}';
s.options[s.length]=new Option('plain text','\n{{{\n,\n}}}\n');
s.options[s.length-1].title='multi-line monospaced text box - {{{...}}}';
s.options[s.length]=new Option('superscript','^^,^^');
s.options[s.length-1].title='^^superscript^^';
s.options[s.length]=new Option('subscript','~~,~~');
s.options[s.length-1].title='~~subscript~~';
s.options[s.length]=new Option('HTML','<html>,<\x2fhtml>');
s.options[s.length-1].title='HTML syntax - <html>...<\x2fhtml>';
s.options[s.length]=new Option('comment','/%,%/');
s.options[s.length-1].title='comment (hidden content) - /%...%/';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>format</a></html>
/%
|Name|QuickEdit_image|
|Source|http://www.TiddlyTools.com/#QuickEdit_image|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar buttons that insert embedded image references|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_image>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_image'></span>
**** INSERT IMAGE ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="embed an image (jpg/gif/png) - [img[tooltip|URL]] or [img[tooltip|path/to/file.ext]]"
onclick="var fn=config.quickEdit.promptForFilename('Enter/select an image file',getLocalPath(document.location.href),'');
if (!fn) return false; /* cancelled by user */
var tip=prompt('Enter a tooltip for this image',''); if (!tip) tip=''; else tip+='|';
return config.quickEdit.setSelection(this,'[img['+tip+fn+']]');"
>image</a></html>
/%
|Name|QuickEdit_link|
|Source|http://www.TiddlyTools.com/#QuickEdit_link|
|Version|2.2.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|toolbar button that inserts a ~PrettyTiddlyLink to a tiddler or external file|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_link>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_link'></span>
**** INSERT LINK ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="add a 'PrettyLink' to another tiddler - [[link text|TiddlerName]]"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select a tiddler or file...','');
s.onchange=function(){
var title=this.value; var txt=title;
if (title=='_file') {
title=config.quickEdit.promptForFilename('Select a file',
getLocalPath(document.location.href),'');
if (!title) { this.selectedIndex=0; this.focus(); return false; }
var txt=title.substr(title.lastIndexOf('/')+1);
}
var txt=prompt('Enter the text to display for this link',txt);
if (!txt) { this.selectedIndex=0; this.focus(); return false; }
config.quickEdit.setSelection(this.button,'[['+txt+'|'+title+']]');
Popup.remove(); return false;
};
s.options[s.length]=new Option('[browse for file...]','_file');
var tids=store.getTiddlers('title');
for (var t=0; t<tids.length; t++) {
s.options[s.length]=new Option(tids[t].title,tids[t].title);
s.options[s.length-1].title=tids[t].getSubtitle();
}
var s=createTiddlyElement(p,'select');
s.options[0]=new Option('match tag...','');
s.onchange=function(){
var tag=this.value;
var tids=tag.length?store.getTaggedTiddlers(tag,'title'):store.getTiddlers('title');
var list=this.previousSibling;
while (list.length) list.options[0]=null;
var prompt='select a tiddler or file...';
if (tag.length) prompt='select a tagged tiddler ['+tids.length+' matches]...';
list.options[0]=new Option(prompt,'');
if (!tag.length) list.options[list.length]=new Option('[browse for file...]','_file');
for (var t=0; t<tids.length; t++) {
list.options[list.length]=new Option(tids[t].title,tids[t].title);
list.options[list.length-1].title=tids[t].getSubtitle();
}
};
var tags=store.getTags();
for (var t=0; t<tags.length; t++) s.options[s.length]=new Option(tags[t][0],tags[t][0]);
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>link</a></html>
/%
|Name|QuickEdit_macro|
|Source|http://www.TiddlyTools.com/#QuickEdit_macro|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button that inserts macros with guide text|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_macro>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_macro'></span>
**** INSERT MACRO ****
The "macro" command can include optional "guideText" for any given macro, as an aide to entering macro parameters, by embedding placeholders or recommended default values into the macro syntax that is inserted into your tiddler content. For built-in TW core macros, this guideText is defined below. You can add guideText to your own plugin-defined macros by using the following javascript syntax: config.macros.macroName.guideText="guide text goes here";
%/<<tiddler {{
/* SET MACRO GUIDE TEXT (for built-in core macros) (11/17 - TBD - incomplete list) */
config.macros.edit.guideText="fieldname #rows";
config.macros.view.guideText="fieldname (link,wikified,date) format";
config.macros.slider.guideText="cookie TiddlerName label tooltip";
config.macros.option.guideText="(txtCookieName,chkCookieName)";
config.macros.tiddler.guideText="TiddlerName with: params...";
""; /* must return blank to suppress output */ }}>>/%
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="add a macro - \<\<macroName ...\>\>"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select a macro...','');
s.onchange=function(){
config.quickEdit.setSelection(this.button,'\<\<'+this.value+'\>\>');
Popup.remove(); return false;
};
var macros=[]; for (var m in config.macros) if (config.macros[m].handler) macros.push(m); macros.sort();
for (var i=0; i<macros.length; i++) { var m=macros[i];
var help=config.macros[m].guideText; if (!help) help=''; else help=' '+help;
s.options[s.length]=new Option(m,m+help);
s.options[s.length-1].title='\<\<'+m+help+'\>\>';
}
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>macro</a></html>
/%
|Name|QuickEdit_replace|
|Source|http://www.TiddlyTools.com/#QuickEdit_replace|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for find/replace toolbar button|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_replace>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_replace'></span>
**** FIND/REPLACE/NEXT/ALL ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="find/replace selected text with replacement text"
onclick="var here=story.findContainingTiddler(this); if (!here) return false;
var e=config.quickEdit.getField(here);
var s=config.quickEdit.getSelection(e);
var p=Popup.create(this,null,'popup sticky smallform'); if (!p) return false;
var t=createTiddlyElement(p,'input'); t.onfocus=function(){this.select()};
t.value=s.length?s:'enter target text';
var r=createTiddlyElement(p,'input'); r.onfocus=function(){this.select()};
r.value='enter replacement text';
var tid=here.getAttribute('tiddler');
var b=createTiddlyElement(p,'button',null,null,'?',{tid:tid});
b.style.width='2em';
b.title='FIND/FIND NEXT target text';
b.onclick=function(ev) { /* FIND */
var e=story.getTiddlerField(this.getAttribute('tid'),'text');
if (!e||e.getAttribute('edit')!='text') return;
var t=this.previousSibling.previousSibling;
e.focus();
if (e.setSelectionRange) { /* MOZ */
var newstart=e.value.indexOf(t.value,e.selectionStart+1);
if (newstart==-1) newstart=e.value.indexOf(t.value); /* wrap around */
if (newstart==-1) { alert('\u0022'+t.value+'\u0022 not found'); t.focus(); return; }
e.setSelectionRange(newstart,newstart+t.value.length);
var linecount=e.value.split('\n').length;
var thisline=e.value.substr(0,e.selectionStart).split('\n').length;
e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);
} else if (document.selection) { /* IE */
var range=document.selection.createRange();
if(range.parentElement()==e) {
range.collapse(false);
var found=false; try{found=range.findText(t.value,e.value.length,4)}catch(e){}
if (found) range.select();
else { alert('\u0022'+t.value+'\u0022 not found'); t.focus(); }
}
}
};
b=createTiddlyElement(p,'button',null,null,'=',{tid:tid});
b.style.width='2em';
b.title='REPLACE selected text';
b.onclick=function(ev) { /* REPLACE */
var e=story.getTiddlerField(this.getAttribute('tid'),'text');
if (!e||e.getAttribute('edit')!='text') return;
var t=this.previousSibling.previousSibling.previousSibling;
var r=this.previousSibling.previousSibling;
if ( (e.selectionStart!==undefined && e.selectionEnd==e.selectionStart)
|| (document.selection && document.selection.createRange().text==''))
this.previousSibling.click(); /* no selection... do FIND first */
if ( (e.selectionStart!==undefined && e.selectionEnd==e.selectionStart)
|| (document.selection && document.selection.createRange().text==''))
{ t.focus(); return; } /* still no selection... goto target input */
e.focus(); replaceSelection(e,r.value);
};
b=createTiddlyElement(p,'button',null,null,'+',{tid:tid});
b.style.width='2em';
b.title='REPLACE selected text AND FIND NEXT target text';
b.onclick=function(ev) { /* REPLACE and FIND NEXT */
this.previousSibling.click();
this.previousSibling.previousSibling.click();
};
b=createTiddlyElement(p,'button',null,null,'!',{tid:tid});
b.style.width='2em';
b.title='REPLACE ALL occurrences of target text';
b.onclick=function(ev) { /* REPLACE ALL */
var e=story.getTiddlerField(this.getAttribute('tid'),'text');
if (!e||e.getAttribute('edit')!='text') return;
var t=this.previousSibling.previousSibling.previousSibling.previousSibling.previousSibling;
var r=this.previousSibling.previousSibling.previousSibling.previousSibling;
if (!t.value.length) { alert('Please enter the target text'); t.focus(); return; }
var m='This will replace all occurences of:\n\n';
m+='\''+t.value+'\'\n\nwith:\n\n\''+r.value+'\'\n\nAre you sure?';
if (!confirm(m)) { r.focus(); r.select(); return; }
e.value=e.value.replace(new RegExp(t.value.escapeRegExp(),'gm'),r.value);
e.focus(); e.select(); Popup.remove();
};
Popup.show(p,false);
if (!s.length) {t.focus();t.select()} else {r.focus();r.select()}
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>replace</a></html>
/%
|Name|QuickEdit_sort|
|Source|http://www.TiddlyTools.com/#QuickEdit_sort|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar "sort" button|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_sort>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_sort'></span>
**** SORT LINES ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="sort lines of text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select sort order...','');
s.onchange=function(){
var e=config.quickEdit.getField(this.button); if (!e) return false;
var lines=config.quickEdit.getSelection(e).split('\n').sort();
if (this.value=='D') lines=lines.reverse();
replaceSelection(e,lines.join('\n'));
e.focus();
Popup.remove(); return false;
};
s.options[s.length]=new Option('ascending','A');
s.options[s.length-1].title='ascending';
s.options[s.length]=new Option('descending','D');
s.options[s.length-1].title='descending';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>sort</a></html>
/%
|Name|QuickEdit_split|
|Source|http://www.TiddlyTools.com/#QuickEdit_split|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|toolbar button: split selected content into separate tiddler|
Based on ideas originally developed by YannPerrin
(http://yann.perrin.googlepages.com/twkd.html#easySlicer)
Usage
QuickEditToolbar: <<tiddler QuickEdit_split>>
OR
EditTemplate:
<div class='toolbar'>
<span macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></span>
<span macro='tiddler QuickEdit_split'></span>
</div>
**** SPLIT TIDDLER ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="move selection to new tiddler and insert link, embedded tiddler, or slider"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
p.style.whiteSpace='nowrap';
var i=createTiddlyElement(p,'input');
i.defaultValue='Enter a new tiddler title';
i.onfocus=function(){this.select()};
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select type...','');
s.options[0].title='select split type';
s.options[1]=new Option('link','link');
s.options[1].title='replace with [[TiddlerName]]';
s.options[2]=new Option('embed','embed');
s.options[2].title='replace with \<\<tiddler TiddlerName\>\>';
s.options[3]=new Option('slider','slider');
s.options[3].title='replace with \<\<slider \u0022\u0022 [[TiddlerName]] [[label]] [[tooltip]]\>\>';
s.onchange=function(){
if (s.previousSibling.value==s.previousSibling.defaultValue)
{ alert('A tiddler title is required'); s.selectedIndex=0; s.previousSibling.focus(); return false; }
var tid=s.previousSibling.value;
if (store.tiddlerExists(tid) && !confirm(config.messages.overwriteWarning.format([tid])))
{ s.previousSibling.focus(); return false; }
switch(s.value) {
case 'link':
var newtxt='[['+tid+']]';
break;
case 'embed':
var newtxt='\<\<tiddler [['+tid+']]\>\>';
break;
case 'slider':
var label=prompt('Enter a slider label',tid);
if (!label) { Popup.remove(); return false; }
var tip=prompt('Enter a slider tooltip',label);
if (!tip) { Popup.remove(); return false; }
var newtxt='\<\<slider \u0022\u0022 [['+tid+']] [['+label+']] [['+tip+']]\>\>';
break;
}
var txt=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
store.saveTiddler(tid,tid,txt,config.options.txtUserName,new Date(),[],{});
story.displayTiddler(story.findContainingTiddler(this.button),tid);
config.quickEdit.setSelection(this.button,newtxt);
Popup.remove(); return false;
};
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>split</a></html>
/%
|Name|QuickEdit_tiddler|
|Source|http://www.TiddlyTools.com/#QuickEdit_tiddler|
|Version|2.2.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.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button that inserts content from another tiddler|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_tiddler>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_tiddler'></span>
**** INSERT TIDDLER ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="copy content from another tiddler"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select a tiddler...','');
s.onchange=function(){
var txt=store.getTiddlerText(this.value);
if (!txt) { displayMessage(this.value+' not found'); this.selectedIndex=0; this.focus(); return false; }
config.quickEdit.setSelection(this.button,txt);
Popup.remove(); return false;
};
var tids=store.getTiddlers('title');
for (var t=0; t<tids.length; t++) {
s.options[s.length]=new Option(tids[t].title,tids[t].title);
s.options[s.length-1].title=tids[t].getSubtitle();
}
var s=createTiddlyElement(p,'select');
s.options[0]=new Option('match tag...','');
s.onchange=function(){
var tag=this.value;
var tids=tag.length?store.getTaggedTiddlers(tag,'title'):store.getTiddlers('title');
var list=this.previousSibling;
while (list.length) list.options[0]=null;
var prompt='select a '+(tag.length?'tagged ':'')+'tiddler'+(tag.length?(' ['+tids.length+' matches]'):'')+'...';
list.options[0]=new Option(prompt,'');
for (var t=0; t<tids.length; t++) {
list.options[list.length]=new Option(tids[t].title,tids[t].title);
list.options[list.length-1].title=tids[t].getSubtitle();
}
};
var tags=store.getTags();
for (var t=0; t<tags.length; t++) s.options[s.length]=new Option(tags[t][0],tags[t][0]);
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>tiddler</a></html>
/***
|Name|QuoteOfTheDayPlugin|
|Source|http://www.TiddlyTools.com/#QuoteOfTheDayPlugin|
|Documentation|http://www.TiddlyTools.com/#QuoteOfTheDayPluginInfo|
|Version|1.4.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Display a randomly selected "quote of the day" from a list defined in a separate tiddler|
!!!!!Documentation
>see [[QuoteOfTheDayPluginInfo]]
!!!!!Revisions
<<<
2008.03.21 [1.4.1] in showNextItem(), corrected handling for random selection so that //initial// index value will randomized correctly instead of always showing first item, even when randomizing. Thanks to Riccardo Gherardi for finding this.
| Please see [[QuoteOfTheDayPluginInfo]] for previous revision details |
2005.10.21 [1.0.0] Initial Release. Based on a suggestion by M.Russula
<<<
!!!!!Code
***/
//{{{
version.extensions.QuoteOfTheDayPlugin= {major: 1, minor: 4, revision: 1, date: new Date(2008,3,21)};
config.macros.QOTD = {
clickTooltip: "click to view another item",
timerTooltip: "auto-timer stopped... 'mouseout' to restart timer",
timerClickTooltip: "auto-timer stopped... click to view another item, or 'mouseout' to restart timer",
handler:
function(place,macroName,params) {
var tid=params.shift(); // source tiddler containing HR-separated quotes
var p=params.shift();
var click=true; // allow click for next item
var inline=false; // wrap in slider for animation effect
var random=true; // pick an item at random (default for "quote of the day" usage)
var folder=false; // use local filesystem folder list
var cookie=""; // default to no cookie
var next=0; // default to first item (or random item)
while (p) {
if (p.toLowerCase()=="noclick") var click=false;
if (p.toLowerCase()=="inline") var inline=true;
if (p.toLowerCase()=="norandom") var random=false;
if (p.toLowerCase().substr(0,7)=="cookie:") var cookie=p.substr(8);
if (!isNaN(p)) var delay=p;
p=params.shift();
}
if ((click||delay) && !inline) {
var panel = createTiddlyElement(null,"div",null,"sliderPanel");
panel.style.display="none";
place.appendChild(panel);
var here=createTiddlyElement(panel,click?"a":"span",null,"QOTD");
}
else
var here=createTiddlyElement(place,click?"a":"span",null,"QOTD");
here.id=(new Date()).convertToYYYYMMDDHHMMSSMMM()+Math.random().toString(); // unique ID
// get items from tiddler or file list
var list=store.getTiddlerText(tid,"");
if (!list||!list.length) { // not a tiddler... maybe an image directory?
var list=this.getImageFileList(tid);
if (!list.length) { // maybe relative path... fixup and try again
var h=document.location.href;
var p=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
var list=this.getImageFileList(p+tid);
}
}
if (!list||!list.length) return false; // no contents... nothing to display!
here.setAttribute("list",list);
if (delay) here.setAttribute("delay",delay);
here.setAttribute("random",random);
here.setAttribute("cookie",cookie);
if (click) {
here.title=this.clickTooltip
if (!inline) here.style.display="block";
here.setAttribute("href","javascript:;");
here.onclick=function(event)
{ config.macros.QOTD.showNextItem(this); }
}
if (config.options["txtQOTD_"+cookie]!=undefined) next=parseInt(config.options["txtQOTD_"+cookie]);
here.setAttribute("nextItem",next);
config.macros.QOTD.showNextItem(here);
if (delay) {
here.title=click?this.timerClickTooltip:this.timerTooltip
here.onmouseover=function(event)
{ clearTimeout(this.ticker); };
here.onmouseout=function(event)
{ this.ticker=setTimeout("config.macros.QOTD.tick('"+this.id+"')",this.getAttribute("delay")); };
here.ticker=setTimeout("config.macros.QOTD.tick('"+here.id+"')",delay);
}
},
tick: function(id) {
var here=document.getElementById(id); if (!here) return;
config.macros.QOTD.showNextItem(here);
here.ticker=setTimeout("config.macros.QOTD.tick('"+id+"')",here.getAttribute("delay"));
},
showNextItem:
function (here) {
// hide containing slider panel (if any)
var p=here.parentNode;
if (p.className=="sliderPanel") p.style.display = "none"
// get a new quote
var index=here.getAttribute("nextItem");
var items=here.getAttribute("list").split("\n----\n");
if (index<0||index>=items.length) index=0;
if (here.getAttribute("random")=="true") index=Math.floor(Math.random()*items.length);
var txt=items[index];
// re-render quote display element, and advance index counter
removeChildren(here); wikify(txt,here);
index++; here.setAttribute("nextItem",index);
var cookie=here.getAttribute("cookie");
if (cookie.length) {
config.options["txtQOTD_"+cookie]=index.toString();
saveOptionCookie("txtQOTD_"+cookie);
}
// redisplay slider panel (if any)
if (p.className=="sliderPanel") {
if(anim && config.options.chkAnimate)
anim.startAnimating(new Slider(p,true,false,"none"));
else p.style.display="block";
}
},
getImageFileList: function(cwd) { // returns HR-separated list of image files
function isImage(fn) {
var ext=fn.substr(fn.length-3,3).toLowerCase();
return ext=="jpg"||ext=="gif"||ext=="png";
}
var files=[];
if (config.browser.isIE) {
cwd=cwd.replace(/\//g,"\\");
// IE uses ActiveX to read filesystem info
var fso = new ActiveXObject("Scripting.FileSystemObject");
if(!fso.FolderExists(cwd)) return [];
var dir=fso.GetFolder(cwd);
for(var f=new Enumerator(dir.Files); !f.atEnd(); f.moveNext())
if (isImage(f.item().path)) files.push("[img[%0]]".format(["file:///"+f.item().path.replace(/\\/g,"/")]));
} else {
// FireFox (mozilla) uses "components" to read filesystem info
// get security access
if(!window.Components) return;
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
catch(e) { alert(e.description?e.description:e.toString()); return []; }
// open/validate directory
var file=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try { file.initWithPath(cwd); } catch(e) { return []; }
if (!file.exists() || !file.isDirectory()) { return []; }
var folder=file.directoryEntries;
while (folder.hasMoreElements()) {
var f=folder.getNext().QueryInterface(Components.interfaces.nsILocalFile);
if (f instanceof Components.interfaces.nsILocalFile)
if (isImage(f.path)) files.push("[img[%0]]".format(["file:///"+f.path.replace(/\\/g,"/")]));
}
}
return files.join("\n----\n");
}
}
//}}}
/***
|Name|RearrangeTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#RearrangeTiddlersPlugin|
|Version|2.0.0|
|Author|Eric Shulman|
|OriginalAuthor|Joe Raii|
|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.refreshTiddler|
|Description|drag tiddlers by title to re-order story column display|
adapted from: http://www.cs.utexas.edu/~joeraii/dragn/#Draggable
changes by ELS:
* hijack refreshTiddler() instead of overridding createTiddler()
* find title element by className instead of elementID
* set cursor style via code instead of stylesheet
* set tooltip help text
* set tiddler "position:relative" when starting drag event, restore saved value when drag ends
* update 2006.08.07: use getElementsByTagName("*") to find title element, even when it is 'buried' deep in tiddler DOM elements (due to custom template usage)
* update 2007.03.01: use apply() to invoke hijacked core function
* update 2008.01.13: only hijack core function once. (allows for dynamic loading of plugin via bookmarklet)
* update 2008.10.19: added onclick popup menu with 'move to top' and 'move to bottom' commands
***/
//{{{
if (Story.prototype.rearrangeTiddlersHijack_refreshTiddler===undefined) {
Story.prototype.rearrangeTiddlersHijack_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template)
{
this.rearrangeTiddlersHijack_refreshTiddler.apply(this,arguments);
var theTiddler = document.getElementById(this.idPrefix + title); if (!theTiddler) return;
var theHandle;
var children=theTiddler.getElementsByTagName("*");
for (var i=0; i<children.length; i++) if (hasClass(children[i],"title")) { theHandle=children[i]; break; }
if (!theHandle) return theTiddler;
Drag.init(theHandle, theTiddler, 0, 0, null, null);
theHandle.style.cursor="move";
theHandle.title="drag title to re-arrange tiddlers, click for more options..."
theTiddler.onDrag = function(x,y,myElem) {
if (this.style.position!="relative")
{ this.savedstyle=this.style.position; this.style.position="relative"; }
y = myElem.offsetTop;
var next = myElem.nextSibling;
var prev = myElem.previousSibling;
if (next && y + myElem.offsetHeight > next.offsetTop + next.offsetHeight/2) {
myElem.parentNode.removeChild(myElem);
next.parentNode.insertBefore(myElem, next.nextSibling);//elems[pos+1]);
myElem.style["top"] = -next.offsetHeight/2+"px";
}
if (prev && y < prev.offsetTop + prev.offsetHeight/2) {
myElem.parentNode.removeChild(myElem);
prev.parentNode.insertBefore(myElem, prev);
myElem.style["top"] = prev.offsetHeight/2+"px";
}
};
theTiddler.onDragEnd = function(x,y,myElem) {
myElem.style["top"] = "0px";
if (this.savedstyle!=undefined)
this.style.position=this.savedstyle;
};
theHandle.onclick=function(ev) {
ev=ev||window.event;
var p=Popup.create(this); if (!p) return;
var b=createTiddlyButton(createTiddlyElement(p,"li"),
"\u25B2 move to top of column ","move this tiddler to the top of the story column",
function() {
var t=story.getTiddler(this.getAttribute("tid"));
t.parentNode.insertBefore(t,t.parentNode.firstChild); // move to top of column
window.scrollTo(0,ensureVisible(t));
return false;
});
b.setAttribute("tid",title);
var b=createTiddlyButton(createTiddlyElement(p,"li"),
"\u25BC move to bottom of column ","move this tiddler to the bottom of the story column",
function() {
var t=story.getTiddler(this.getAttribute("tid"));
t.parentNode.insertBefore(t,null); // move to bottom of column
window.scrollTo(0,ensureVisible(t));
return false;
});
b.setAttribute("tid",title);
Popup.show(p,false);
ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); return(false);
};
return theTiddler;
}
}
/**************************************************
* dom-drag.js
* 09.25.2001
* www.youngpup.net
**************************************************
* 10.28.2001 - fixed minor bug where events
* sometimes fired off the handle, not the root.
**************************************************/
var Drag = {
obj:null,
init:
function(o, oRoot, minX, maxX, minY, maxY) {
o.onmousedown = Drag.start;
o.root = oRoot && oRoot != null ? oRoot : o ;
if (isNaN(parseInt(o.root.style.left))) o.root.style.left="0px";
if (isNaN(parseInt(o.root.style.top))) o.root.style.top="0px";
o.minX = typeof minX != 'undefined' ? minX : null;
o.minY = typeof minY != 'undefined' ? minY : null;
o.maxX = typeof maxX != 'undefined' ? maxX : null;
o.maxY = typeof maxY != 'undefined' ? maxY : null;
o.root.onDragStart = new Function();
o.root.onDragEnd = new Function();
o.root.onDrag = new Function();
},
start:
function(e) {
var o = Drag.obj = this;
e = Drag.fixE(e);
var y = parseInt(o.root.style.top);
var x = parseInt(o.root.style.left);
o.root.onDragStart(x, y, Drag.obj.root);
o.lastMouseX = e.clientX;
o.lastMouseY = e.clientY;
if (o.minX != null) o.minMouseX = e.clientX - x + o.minX;
if (o.maxX != null) o.maxMouseX = o.minMouseX + o.maxX - o.minX;
if (o.minY != null) o.minMouseY = e.clientY - y + o.minY;
if (o.maxY != null) o.maxMouseY = o.minMouseY + o.maxY - o.minY;
document.onmousemove = Drag.drag;
document.onmouseup = Drag.end;
Drag.obj.root.style["z-index"] = "10";
return false;
},
drag:
function(e) {
e = Drag.fixE(e);
var o = Drag.obj;
var ey = e.clientY;
var ex = e.clientX;
var y = parseInt(o.root.style.top);
var x = parseInt(o.root.style.left);
var nx, ny;
if (o.minX != null) ex = Math.max(ex, o.minMouseX);
if (o.maxX != null) ex = Math.min(ex, o.maxMouseX);
if (o.minY != null) ey = Math.max(ey, o.minMouseY);
if (o.maxY != null) ey = Math.min(ey, o.maxMouseY);
nx = x + (ex - o.lastMouseX);
ny = y + (ey - o.lastMouseY);
Drag.obj.root.style["left"] = nx + "px";
Drag.obj.root.style["top"] = ny + "px";
Drag.obj.lastMouseX = ex;
Drag.obj.lastMouseY = ey;
Drag.obj.root.onDrag(nx, ny, Drag.obj.root);
return false;
},
end:
function() {
document.onmousemove = null;
document.onmouseup = null;
Drag.obj.root.style["z-index"] = "0";
Drag.obj.root.onDragEnd(parseInt(Drag.obj.root.style["left"]), parseInt(Drag.obj.root.style["top"]), Drag.obj.root);
Drag.obj = null;
},
fixE:
function(e) {
if (typeof e == 'undefined') e = window.event;
if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
return e;
}
};
//}}}
<<tiddler HideTiddlerBackground>><<tiddler HideTiddlerTags>>{{transparent smallform{<<recentChanges 30>>}}}
/***
|Name|RecentChangesPlugin|
|Source|http://www.TiddlyTools.com/#RecentChangesPlugin|
|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||
|Overrides||
|Description|display droplist of recently changed tiddlers with goto, edit, and preview buttons|
!!!!!Usage
<<<
The {{{<<recentChanges>>}}} macro displays a droplist of all tiddlers that have been changed within the last N days (default=10 days).
<<<
!!!!!Examples
<<<
{{smallform{
{{{<<recentChanges>>}}}
><<recentChanges>>
or
{{{<<recentChanges #ofdays summary>>}}}
>where:
>* #ofdays specifies the time limit for list changed tiddlers. Use 0 (zero) to list all tiddlers in the document
>* "summary" is a keyword that outputs only the summary text (without the droplist or buttons)
>{{{<<recentChanges 14 summary>>}}}
><<recentChanges 14 summary>>
or
{{{<<recentChanges #ofdays previewheight previewclass>>}}}
>where:
>* #ofdays specifies the time limit for list changed tiddlers. Use 0 (zero) to list all tiddlers in the document
>* previewheight is a CSS height measurement and sets the FIXED height of the tiddler preview area (default is 15em)
>* previewclass is any CSS classname, and can be used to apply custom styles to the preview area (default is to use the standard 'viewer' class)
>{{{<<recentChanges 14 10em groupbox>>}}}
><<recentChanges 14 10em groupbox>>
}}}
<<<
!!!!!Revisions
<<<
2008.07.01 [2.1.0] added optional "summary" keyword for simply text output
2008.05.01 [2.0.1] fixup for titles with double-quotes
2007.07.26 [2.0.0] re-written as plugin
2006.10.02 [1.0.0] initial release (as inline script ShowRecentChanges)
<<<
!!!!!Code
***/
//{{{
version.extensions.RecentChangesPlugin= {major: 2, minor: 1, revision: 0, date: new Date(2008,7,1)};
config.shadowTiddlers.RecentChanges="<<recentChanges>>";
config.macros.recentChanges = {
layout: '<form><!--\
--><select size=1 name="list" style="width:69.5%" \
onchange=" \
this.form.goto.disabled=this.form.edit.disabled=this.form.preview.disabled=!this.value.length; \
var target=this.parentNode.parentNode.nextSibling; removeChildren(target); \
if (!this.value.length) \
{ target.style.display=\'none\'; this.form.preview.value=\'preview\'; } \
else if (target.style.display==\'block\') { \
wikify(\'<\'+\'<tiddler [[\'+this.value+\']]>\'+\'>\',target); \
target.style.display=\'block\'; \
this.form.preview.value=\'done\'; \
} \
"><!--\
-->%options%<!--\
--></select><!--\
--><input type="button" name="goto" value="goto" disabled title="view selected tiddler" style="width:10%" \
onclick="var target=this.parentNode.parentNode.nextSibling; removeChildren(target); \
target.style.display=\'none\'; this.form.preview.value=\'preview\'; \
story.displayTiddler(story.findContainingTiddler(this),this.form.list.value); \
"><!--\
--><input type="button" name="edit" value="edit" disabled title="edit selected tiddler" style="width:10%" \
onclick="var target=this.parentNode.parentNode.nextSibling; removeChildren(target); \
target.style.display=\'none\'; this.form.preview.value=\'preview\'; \
story.displayTiddler(story.findContainingTiddler(this),this.form.list.value,DEFAULT_EDIT_TEMPLATE); \
"><!--\
--><input type="button" name="preview" value="preview" disabled title="show/hide tiddler preview" style="width:10%" \
onclick="var target=this.parentNode.parentNode.nextSibling; \
if (this.value==\'preview\') { \
removeChildren(target); \
wikify(\'<\'+\'<tiddler [[\'+this.form.list.value+\']]>\'+\'>\',target); \
target.style.display=this.form.list.value.length?\'block\':\'none\'; this.value=\'done\'; \
} else { \
removeChildren(target); \
target.style.display=\'none\'; this.value=\'preview\'; \
} \
"><!--\
--></form>',
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var days=10; if (!isNaN(params[0])) days=parseInt(params[0]); // time limit in days (use 0 for all tiddlers)
var summary=params[1]&¶ms[1].toLowerCase()=="summary"; if (summary) params.shift();
var height='15em'; if (params[1]) height=params[1]; // preview area fixed height
var previewclass='viewer'; if (params[2]) previewclass=params[2]; // preview area CSS class
var tiddlers=store.getTiddlers('modified','excludeLists').reverse();
var count=tiddlers.length;
if (days) {
var timelimit=(new Date()).getTime()-86400000*days;
for (var count=0; count<tiddlers.length && tiddlers[count].modified>timelimit; count++);
}
var s=count+' tiddlers have changed since ';
s+=new Date(timelimit).formatString("DDD, MMM DDth YYYY 0hh:0mm");
s+=' ('+days+' days ago)';
if (summary)
{ wikify(s,place); return; }
var opts='<option value="">'+s+'</option>';
for (var i=0; i<count; i++) { var t=tiddlers[i];
opts+='<option value="'+t.title.replace(/"/g,""")+'">';
opts+=t.modified.formatString('YYYY.0MM.0DD 0hh:0mm')+' - '+t.title;
opts+='</option>';
}
createTiddlyElement(place,"div").innerHTML=this.layout.replace(/%options%/,opts);
var preview=createTiddlyElement(place,"div",null,previewclass);
preview.style.display='none';
preview.style.whiteSpace='normal';
preview.style.overflow='auto';
preview.style.height=height;
}
}
//}}}
<script label="refresh" title="re-render this tiddler">
var here=story.findContainingTiddler(place); if (!here) return false;
story.refreshTiddler(here.getAttribute("tiddler"),null,true);
</script><script>place.lastChild.className='button';</script>
/%
|Name|ReplaceTiddlerTitle|
|Source|http://www.TiddlyTools.com/#ReplaceTiddlerTitle|
|Version|1.0.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|replace tiddler's title text with other content - may include wiki syntax|
Usage:
<<tiddler ReplaceTiddlerTitle with: "new title text">>
%/<script>
// get the tiddler element
var here=story.findContainingTiddler(place);
if (!here || here.getAttribute("tiddler")=="ReplaceTiddlerTitle") return; // don't change the title on the script itself!
var nodes=here.getElementsByTagName("*");
for (var i=0; i<nodes.length; i++)
if (hasClass(nodes[i],"title")) { removeChildren(nodes[i]); wikify("$1",nodes[i]); break; }
</script>
/***
|Name|SaveAsPlugin|
|Source|http://www.TiddlyTools.com/#SaveAsPlugin|
|Documentation|http://www.TiddlyTools.com/#SaveAsPluginInfo|
|Version|2.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|Save current document to a different path/filename|
This plugin automatically adds a 'save as' command to the TiddlyWiki 'backstage' menu that allows you to quickly create an exact copy of the current TiddlyWiki document. The plugin also defines a macro that you can use to place a "save as..." command link into your sidebar/mainmenu/any tiddler (or wherever you like).
>//Note: This plugin now supersedes [[NewDocumentPlugin]], which has been retired and is no longer being distributed. In addition, the HTML+CSS "snapshot" functionality previous provided by that plugin has been moved to a separate plugin. Please see [[SnapshotPlugin]] for additional information.//
!!!!!Documentation
<<<
see [[SaveAsPluginInfo]]
<<<
!!!!!Revisions
<<<
2008.09.29 [2.4.3] in getData(), convert existing TW file from UTF8 to Unicode before merging to correct handling of international characters and symbols.
| Please see [[SaveAsPluginInfo]] for additional revision details |
2006.02.03 [1.0.0] Created.
<<<
!!!!!Code
***/
//{{{
version.extensions.SaveAsPlugin= {major: 2, minor: 4, revision: 2, date: new Date(2008,9,28)};
config.macros.saveAs = {
label: "save as...",
labelparam: "label:",
prompt: "Save current document to a different path/file",
promptparam: "prompt:",
filePrompt: "Please select or enter a target path/filename",
targetparam: "target:",
defaultFilename: "new.html",
filenameparam: "filename:",
currfilekeyword: "here",
typeparam: "type:",
type_TW: "tw", type_PS: "ps", type_TX: "tx", type_NF: "nf", // file type tokens
type_map: { // map filetype param alternatives/abbreviations to token values
tiddlywiki:"tw", tw:"tw", wiki: "tw",
purestore: "ps", ps:"ps", store:"ps",
plaintext: "tx", tx:"tx", text: "tx",
newsfeed: "nf", nf:"nf", xml: "nf", rss:"nf"
},
replaceparam: "replace",
mergeparam: "merge",
quietparam: "quiet",
openparam: "open",
askParam: "ask",
askMsg: "Enter a tag filter (use * for all tiddlers, 'none' for blank document)",
emptyParam: "none",
confirmmsg: "Found %0 tiddlers matching\n\n'%1'\n\nPress OK to proceed",
mergeprompt: "%0\nalready contains tiddler definitions.\n"
+"\nPress OK to add new/revised tiddlers to current file contents."
+"\nPress Cancel to completely replace file contents",
mergestatus: "Merged %0 new/revised tiddlers and %1 existing tiddlers",
okmsg: "%0 tiddlers written to %1",
failmsg: "An error occurred while creating %1",
filter: "",
handler: function(place,macroName,params) {
if (params[0] && params[0].substr(0,this.labelparam.length)==this.labelparam)
var label=params.shift().substr(this.labelparam.length);
if (params[0] && params[0].substr(0,this.promptparam.length)==this.promptparam)
var prompt=params.shift().substr(this.promptparam.length);
if (params[0] && params[0].substr(0,this.targetparam.length)==this.targetparam)
var target=params.shift().substr(this.targetparam.length);
if (params[0] && params[0].substr(0,this.filenameparam.length)==this.filenameparam)
var filename=params.shift().substr(this.filenameparam.length);
if (params[0] && params[0].substr(0,this.typeparam.length)==this.typeparam)
var filetype=this.type_map[params.shift().substr(this.typeparam.length).toLowerCase()];
var q=(params[0] && params[0]==this.quietparam); if (q) params.shift();
var o=(params[0] && params[0]==this.replaceparam); if (o) params.shift();
var m=(params[0] && params[0]==this.mergeparam); if (m) params.shift();
var a=(params[0] && params[0]==this.openparam); if (a) params.shift();
var btn=createTiddlyButton(place,label||this.label,prompt||this.prompt,
function(){config.macros.saveAs.go(
this.getAttribute('target'),
this.getAttribute('filename'),
this.getAttribute('filetype'),
this.getAttribute('filter'),
this.getAttribute('quiet')=="true",
this.getAttribute('overwrite')=="true",
this.getAttribute('merge')=="true",
this.getAttribute('autoopen')=="true"); return false;}
);
if (target) btn.setAttribute("target",target);
if (filename) btn.setAttribute("filename",filename);
btn.setAttribute("filetype",filetype||this.type_TW);
btn.setAttribute("filter",params.join(" "));
btn.setAttribute("quiet",q?"true":"false");
btn.setAttribute("overwrite",o?"true":"false");
btn.setAttribute("merge",m?"true":"false");
btn.setAttribute("autoopen",a?"true":"false");
},
go: function(target,filename,filetype,filter,quiet,overwrite,merge,autoopen) {
var cm=config.messages; // abbreviation
var cms=config.macros.saveAs; // abbreviation
if (window.location.protocol!="file:") // make sure we are local
{ displayMessage(cm.notFileUrlError); return; }
// get tidders, confirm filtered results
var tids=cms.selectTiddlers(filter);
if (tids===false) return; // cancelled by user
if (cms.filter!=cms.emptyParam && cms.filter.length && !quiet)
if (!confirm(cms.confirmmsg.format([tids.length,cms.filter]))) return;
// get target path/filename
if (!filetype) filetype=this.type_TW;
target=target||cms.getTarget(filename,filetype==this.type_TX?'txt':'html');
if (!target) return; // cancelled by user
var link="file:///"+target.replace(/\\/g,'/');
var samefile=link==decodeURIComponent(window.location.href);
var p=getLocalPath(document.location.href);
if (samefile) {
if (config.options.chkSaveBackups) { var t=loadOriginal(p);if(t)saveBackup(p,t); }
if (config.options.chkGenerateAnRssFeed && saveRss instanceof Function) saveRss(p);
}
var notes="";
var total={val:0};
var out=this.assembleFile(target,filetype,tids,notes,quiet,overwrite,merge,total);
var ok=saveFile(target,out);
if (ok && autoopen) {
if (!samefile) window.open(link).focus();
else { store.setDirty(false); window.location.reload(); }
}
if (!quiet || !(ok && autoopen))
displayMessage((ok?this.okmsg:this.failmsg).format([total.val,target]),link);
},
selectTiddlers: function(filter) {
var cms=config.macros.saveAs; // abbreviation
cms.filter=filter||"";
if (filter==cms.emptyParam) return [];
if (!filter||!filter.length) return store.getTiddlers("title");
// get filtered tiddlers
if (filter==config.macros.saveAs.askParam) {
filter=prompt(config.macros.saveAs.askMsg,"");
if (!filter) return false; // cancelled by user
cms.filter=filter=="*"?"":filter;
if (filter=="*") return store.getTiddlers("title");
}
return store.filterTiddlers("[tag["+filter+"]]");
},
getTarget: function(defName,defExt) {
var cms=config.macros.saveAs; // abbreviation
// get new target path/filename
var newPath=getLocalPath(window.location.href);
var slashpos=newPath.lastIndexOf("/"); if (slashpos==-1) slashpos=newPath.lastIndexOf("\\");
if (slashpos!=-1) newPath=newPath.substr(0,slashpos+1); // trim filename
if (!defName||!defName.length) { // use current filename as default
var p=getLocalPath(window.location.href);
var s=p.lastIndexOf("/"); if (s==-1) s=p.lastIndexOf("\\");
if (s!=-1) defName=p.substr(s+1);
}
var defFilename=(defName||cms.defaultFilename).replace(/.html$/,'.'+defExt);
var target=cms.askForFilename(cms.filePrompt,newPath,defFilename,defExt);
if (!target) return; // cancelled by user
// if specified file does not include a path, assemble fully qualified path and filename
var slashpos=target.lastIndexOf("/"); if (slashpos==-1) slashpos=target.lastIndexOf("\\");
if (slashpos==-1) target=target+(defName||cms.defaultFilename).replace(/.html$/,'.'+defExt);
return target;
},
askForFilename: function(msg,path,file,defExt) {
if(window.Components) { // moz
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension=defExt||'html';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
}
catch(e) { alert('error during local file access: '+e.toString()) }
}
else { // IE
try { // XP/Vista only
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
s.FilterIndex=(defExt=='txt')?2:3; // default to HTML files;
s.InitialDir=path;
s.FileName=file;
if (s.showOpen()) var result=s.FileName;
}
catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
}
return result;
},
plainTextHeader:
'// Source'+':\n//\t%0\n'
+'// Title:\n//\t%1\n'
+'// Subtitle:\n//\t%2\n'
+'// Created:\n//\t%3 by %4\n'
+'// Application:\n//\tTiddlyWiki %5 / %6 %7\n',
plainTextTiddler:
'\n// ----- %0 (by %1 on %2) -----\n\n%3',
plainTextFooter:
'',
newsFeedHeader:
'<'+'?xml version="1.0"?'+'>\n'
+'<rss version="2.0">\n'
+'<channel>\n'
+'<title>%1</title>\n'
+'<link>%0</link>\n'
+'<description>%2</description>\n'
+'<language>en-us</language>\n'
+'<copyright>Copyright '+(new Date().getFullYear())+' %4</copyright>\n'
+'<pubDate>%3</pubDate>\n'
+'<lastBuildDate>%3</lastBuildDate>\n'
+'<docs>http://blogs.law.harvard.edu/tech/rss</docs>\n'
+'<generator>TiddlyWiki %5 / %6 %7</generator>\n',
newsFeedTiddler:
'\n%0\n',
newsFeedFooter:
'</channel></rss>',
pureStoreHeader:
'<html><body>'
+'<style type="text/css">'
+' #storeArea {display:block;margin:1em;}'
+' #storeArea div {padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}'
+' #pureStoreHeading {width:100%;text-align:left;background-color:#eeeeee;padding:1em;}'
+'</style>'
+'<div id="pureStoreHeading">'
+' TiddlyWiki "PureStore" export file<br>'
+' Source'+': <b>%0</b><br>'
+' Title: <b>%1</b><br>'
+' Subtitle: <b>%2</b><br>'
+' Created: <b>%3</b> by <b>%4</b><br>'
+' TiddlyWiki %5 / %6 %7<br>'
+' Notes:<hr><pre>%8</pre>'
+'</div>'
+'<div id="storeArea">',
pureStoreTiddler:
'%0\n%1',
pureStoreFooter:
'</div><!--POST-BODY-START-->\n<!--POST-BODY-END--></body></html>',
assembleFile: function(target,filetype,tids,notes,quiet,overwrite,merge,total) {
var revised="";
var now = new Date().toLocaleString();
var src=convertUnicodeToUTF8(document.location.href);
var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
var twver = version.major+"."+version.minor+"."+version.revision;
var v=version.extensions.SaveAsPlugin; var pver = v.major+"."+v.minor+"."+v.revision;
var headerargs=[src,title,subtitle,now,user,twver,"SaveAsPlugin",pver,notes];
switch (filetype) {
case this.type_TX: // plain text
var header=this.plainTextHeader.format(headerargs);
var footer=this.plainTextFooter;
break;
case this.type_NF: // news feed (XML)
headerargs[0]=store.getTiddlerText("SiteUrl","");
var header=this.newsFeedHeader.format(headerargs);
var footer=this.newsFeedFooter;
break;
case this.type_PS: // PureStore (no code)
var header=this.pureStoreHeader.format(headerargs);
var footer=this.pureStoreFooter;
break;
case this.type_TW: // full TiddlyWiki
default:
var currPath=getLocalPath(window.location.href);
var original=loadFile(currPath);
if (!original) { alert(config.messages.cantSaveError); return; }
var posDiv = locateStoreArea(original);
if (!posDiv) { alert(config.messages.invalidFileError.format([currPath])); return; }
var header = original.substr(0,posDiv[0]+startSaveArea.length)+"\n";
var footer = "\n"+original.substr(posDiv[1]);
break;
}
var out=this.getData(target,filetype,tids,quiet,overwrite,merge);
var revised = header+convertUnicodeToUTF8(out.join("\n"))+footer;
// if full TW, insert page title and language attr, and reset MARKUP blocks as needed...
if (filetype==this.type_TW) {
var newSiteTitle=convertUnicodeToUTF8(getPageTitle()).htmlEncode();
revised=revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised=updateLanguageAttribute(revised);
var titles=[]; for (var i=0; i<tids.length; i++) titles.push(tids[i].title);
revised=updateMarkupBlock(revised,"PRE-HEAD",
titles.contains("MarkupPreHead")? "MarkupPreHead" :null);
revised=updateMarkupBlock(revised,"POST-HEAD",
titles.contains("MarkupPostHead")?"MarkupPostHead":null);
revised=updateMarkupBlock(revised,"PRE-BODY",
titles.contains("MarkupPreBody")? "MarkupPreBody" :null);
revised=updateMarkupBlock(revised,"POST-SCRIPT",
titles.contains("MarkupPostBody")?"MarkupPostBody":null);
}
total.val=out.length;
return revised;
},
formatItem: function(s,f,t,u) {
if (f==this.type_TW) var r=s.getSaver().externalizeTiddler(s,t);
if (f==this.type_PS) var r=this.pureStoreTiddler.format([t.title,s.getSaver().externalizeTiddler(s,t)]);
if (f==this.type_NF) var r=this.newsFeedTiddler.format([t.saveToRss(u)]);
if (f==this.type_TX) var r=this.plainTextTiddler.format([t.title,t.modifier,t.modified.toLocaleString(),t.text]);
return r||"";
},
getData: function(target,filetype,tids,quiet,overwrite,merge) {
// output selected tiddlers and gather list of titles (for use with merge)
var out=[]; var titles=[];
var url=store.getTiddlerText("SiteUrl","");
for (var i=0; i<tids.length; i++) {
out.push(this.formatItem(store,filetype,tids[i],url));
titles.push(tids[i].title);
}
// if TW or PureStore format, ask to merge with existing tiddlers (if any)
if (filetype==this.type_TW || filetype==this.type_PS) {
if (overwrite) return out; // skip merge... forced overwrite
var text=loadFile(target);
if (text && text.length) {
var remoteStore=new TiddlyWiki();
if (remoteStore.importTiddlyWiki(convertUTF8ToUnicode(text))
&& (merge||confirm(this.mergeprompt.format([target])))) {
var existing=remoteStore.getTiddlers("title");
for (var i=0; i<existing.length; i++)
if (!titles.contains(existing[i].title))
out.push(this.formatItem(remoteStore,filetype,existing[i],url));
if (!quiet) displayMessage(this.mergestatus.format([tids.length,out.length-tids.length]));
}
}
}
return out;
}
};
//}}}
//{{{
// automatically add saveAs to backstage
config.tasks.saveAs = {
text: "saveAs",
tooltip: config.macros.saveAs.prompt,
action: function(){ clearMessage(); config.macros.saveAs.go(); }
}
config.backstageTasks.splice(config.backstageTasks.indexOf("save")+1,0,"saveAs");
//}}}
/%
|Name|ScrollBox|
|Source|http://www.TiddlyTools.com/#ScrollBox|
|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|transcluded wiki syntax|
|Requires||
|Overrides||
|Description|display the contents of a tiddler in a fixed-height scrolling area|
%//%
Usage: <<tiddler ScrollBox with: TiddlerName height>>
%/@@display:block;height:$2;overflow:auto;<<tiddler $1>>@@@@display:block;text-align:right;^^scroll for more...^^@@
/***
|Name|SearchOptionsPlugin|
|Source|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#SearchOptionsPluginInfo|
|Version|3.0.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|Story.prototype.search, TiddlyWiki.prototype.search, config.macros.search.onKeyPress|
|Options|##Configuration|
|Description|extend core search function with additional user-configurable options|
Adds extra options to core search function including selecting which data items to search, enabling/disabling incremental key-by-key searches, and generating a ''list of matching tiddlers'' 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 chkSearchHighlight>> Highlight matching text in displayed tiddlers
<<option chkSearchList>> Show list of matches
<<option chkSearchListTiddler>> Write list to [[SearchResults]] tiddler
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchByDate>> Sort matching tiddlers by modification date (most recent first)
<<option chkIncrementalSearch>> Incremental key-by-key search: {{twochar{<<option txtIncrementalSearchMin>>}}} or more characters, {{threechar{<<option txtIncrementalSearchDelay>>}}} msec delay
<<option chkSearchOpenTiddlers>> Search only in tiddlers that are currently displayed
<<option chkSearchExcludeTags>> Exclude tiddlers tagged with: <<option txtSearchExcludeTags>>
<<<
!!!!!Revisions
<<<
2009.01.16 [3.0.5] added chkSearchOpenTiddlers option to limit searches to displayed tiddlers only
|please see [[SearchOptionsPluginInfo]] for additional revision details|
2005.10.18 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.SearchOptionsPlugin= {major: 3, minor: 0, revision: 5, date: new Date(2009,1,16)};
var co=config.options; // abbrev
if (co.chkSearchTitles===undefined) co.chkSearchTitles=true;
if (co.chkSearchText===undefined) co.chkSearchText=true;
if (co.chkSearchTags===undefined) co.chkSearchTags=true;
if (co.chkSearchFields===undefined) co.chkSearchFields=true;
if (co.chkSearchTitlesFirst===undefined) co.chkSearchTitlesFirst=true;
if (co.chkSearchList===undefined) co.chkSearchList=true;
if (co.chkSearchHighlight===undefined) co.chkSearchHighlight=true;
if (co.chkSearchListTiddler===undefined) co.chkSearchListTiddler=false;
if (co.chkSearchByDate===undefined) co.chkSearchByDate=false;
if (co.chkIncrementalSearch===undefined) co.chkIncrementalSearch=true;
if (co.chkSearchShadows===undefined) co.chkSearchShadows=true;
if (co.txtIncrementalSearchDelay===undefined) co.txtIncrementalSearchDelay=500;
if (co.txtIncrementalSearchMin===undefined) co.txtIncrementalSearchMin=3;
if (co.chkSearchOpenTiddlers===undefined) co.chkSearchOpenTiddlers=false;
if (co.chkSearchExcludeTags===undefined) co.chkSearchExcludeTags=true;
if (co.txtSearchExcludeTags===undefined) co.txtSearchExcludeTags="excludeSearch";
if (config.macros.search.reportTitle==undefined)
config.macros.search.reportTitle="SearchResults"; // note: not a cookie!
config.macros.search.label+="\xa0"; // a little bit of space just because it looks better
//}}}
// // searchLink: {{{[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;
}
}
});
//}}}
// // incremental search uses option settings instead of hard-coded delay and minimum input values
//{{{
var fn=config.macros.search.onKeyPress;
fn=fn.toString().replace(/500/g, "config.options.txtIncrementalSearchDelay||500");
fn=fn.toString().replace(/> 2/g, ">=(config.options.txtIncrementalSearchMin||3)");
eval("config.macros.search.onKeyPress="+fn);
//}}}
// // REPLACE story.search() for option to "show search results in a list"
//{{{
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
{
var co=config.options; // abbrev
var re=new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
if (config.options.chkSearchHighlight) highlightHack=re;
var matches = store.search(re,co.chkSearchByDate?"modified":"title","");
if (co.chkSearchByDate) matches=matches.reverse(); // most recent first
var q = useRegExp ? "/" : "'";
clearMessage();
if (!matches.length) {
if (co.chkSearchListTiddler) discardSearchResults();
displayMessage(config.macros.search.failureMsg.format([q+text+q]));
} else {
if (co.chkSearchList||co.chkSearchListTiddler)
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;
}
//}}}
// // REPLACE store.search() for enhanced searching/sorting options
//{{{
TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)
{
var co=config.options; // abbrev
var tids = this.reverseLookup("tags",excludeTag,false,sortField);
var opened=[]; story.forEachTiddler(function(tid,elem){opened.push(tid);});
// eliminate tiddlers tagged with excluded tags
if (co.chkSearchExcludeTags&&co.txtSearchExcludeTags.length) {
var ex=co.txtSearchExcludeTags.readBracketedList();
var temp=[]; for(var t=tids.length-1; t>=0; t--)
if (!tids[t].tags.containsAny(ex)) temp.push(tids[t]);
tids=temp;
}
// scan for matching titles first...
var results = [];
if (co.chkSearchTitles) {
for(var t=0; t<tids.length; t++) {
if (co.chkSearchOpenTiddlers && !opened.contains(tids[t].title)) continue;
if(tids[t].title.search(searchRegExp)!=-1) results.push(tids[t]);
}
if (co.chkSearchShadows)
for (var t in config.shadowTiddlers) {
if (co.chkSearchOpenTiddlers && !opened.contains(t)) continue;
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<tids.length; t++) {
if (co.chkSearchOpenTiddlers && !opened.contains(tids[t].title)) continue;
if (co.chkSearchText && tids[t].text.search(searchRegExp)!=-1)
results.pushUnique(tids[t]);
if (co.chkSearchTags && tids[t].tags.join(" ").search(searchRegExp)!=-1)
results.pushUnique(tids[t]);
if (co.chkSearchFields && store.forEachField!=undefined)
store.forEachField(tids[t],
function(tid,field,val) {
if (val.search(searchRegExp)!=-1) results.pushUnique(tids[t]);
},
true); // extended fields only
}
// then check for matching text in shadows
if (co.chkSearchShadows)
for (var t in config.shadowTiddlers) {
if (co.chkSearchOpenTiddlers && !opened.contains(t)) continue;
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 (!co.chkSearchTitlesFirst || co.chkSearchByDate) results.sort(bySortField);
return results;
}
//}}}
// // 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);
};
//}}}
// // SearchResults panel handling
//{{{
setStylesheet(".searchResults { padding:1em 1em 0 1em; }","searchResults"); // matches std tiddler padding
config.macros.search.createPanel=function(text,matches,body) {
function getByClass(e,c) { var d=e.getElementsByTagName("div");
for (var i=0;i<d.length;i++) if (hasClass(d[i],c)) return d[i]; }
var panel=createTiddlyElement(null,"div","searchPanel","searchPanel");
this.renderPanel(panel,text,matches,body);
var oldpanel=document.getElementById("searchPanel");
if (!oldpanel) { // insert new panel just above tiddlers
var da=document.getElementById("displayArea");
da.insertBefore(panel,da.firstChild);
} else { // if panel exists
var oldwrap=getByClass(oldpanel,"searchResults");
var newwrap=getByClass(panel,"searchResults");
// if no prior content, just insert new content
if (!oldwrap) oldpanel.insertBefore(newwrap,null);
else { // swap search results content but leave containing panel intact
oldwrap.style.display='block'; // unfold wrapper if needed
var i=oldwrap.getElementsByTagName("input")[0]; // get input field
if (i) { var pos=this.getCursorPos(i); i.onblur=null; } // get cursor pos, ignore blur
oldpanel.replaceChild(newwrap,oldwrap);
panel=oldpanel; // use existing panel
}
}
this.showPanel(true,pos);
return panel;
}
config.macros.search.renderPanel=function(panel,text,matches,body) {
var wrap=createTiddlyElement(panel,"div",null,"searchResults");
wrap.onmouseover = function(e){ addClass(this,"selected"); }
wrap.onmouseout = function(e){ removeClass(this,"selected"); }
// create toolbar: "open all", "fold/unfold", "close"
var tb=createTiddlyElement(wrap,"div",null,"toolbar");
var b=createTiddlyButton(tb, "open all", "open all matching tiddlers", function() {
story.displayTiddlers(null,this.getAttribute("list").readBracketedList()); return false; },"button");
var list=""; for(var t=0;t<matches.length;t++) list+='[['+matches[t].title+']] ';
b.setAttribute("list",list);
var b=createTiddlyButton(tb, "fold", "toggle display of search results", function() {
config.macros.search.foldPanel(this); return false; },"button");
var b=createTiddlyButton(tb, "close", "dismiss search results", function() {
config.macros.search.showPanel(false); return false; },"button");
createTiddlyText(createTiddlyElement(wrap,"div",null,"title"),"Search for: "+text); // title
wikify(body,createTiddlyElement(wrap,"div",null,"viewer")); // report
return panel;
}
config.macros.search.showPanel=function(show,pos) {
var panel=document.getElementById("searchPanel");
var i=panel.getElementsByTagName("input")[0];
i.onfocus=show?function(){config.macros.search.stayFocused(true);}:null;
i.onblur=show?function(){config.macros.search.stayFocused(false);}:null;
if (show && panel.style.display=="block") { // if shown, grab focus, restore cursor
if (i&&this.stayFocused()) { i.focus(); this.setCursorPos(i,pos); }
return;
}
if(!config.options.chkAnimate) {
panel.style.display=show?"block":"none";
if (!show) { removeChildren(panel); config.macros.search.stayFocused(false); }
} else {
var s=new Slider(panel,show,false,show?"none":"children");
s.callback=function(e,p){e.style.overflow="visible";}
anim.startAnimating(s);
}
return panel;
}
config.macros.search.foldPanel=function(button) {
var d=document.getElementById("searchPanel").getElementsByTagName("div");
for (var i=0;i<d.length;i++) if (hasClass(d[i],"viewer")) var v=d[i]; if (!v) return;
var show=v.style.display=="none";
if(!config.options.chkAnimate)
v.style.display=show?"block":"none";
else {
var s=new Slider(v,show,false,"none");
s.callback=function(e,p){e.style.overflow="visible";}
anim.startAnimating(s);
}
button.innerHTML=show?"fold":"unfold";
return false;
}
config.macros.search.stayFocused=function(keep) { // TRUE/FALSE=set value, no args=get value
if (keep===undefined) return this.keepReportInFocus;
this.keepReportInFocus=keep;
return keep
}
config.macros.search.getCursorPos=function(i) {
var s=0; var e=0; if (!i) return { start:s, end:e };
try {
if (i.setSelectionRange) // FF
{ s=i.selectionStart; e=i.selectionEnd; }
if (document.selection && document.selection.createRange) { // IE
var r=document.selection.createRange().duplicate();
var len=r.text.length; s=0-r.moveStart('character',-100000); e=s+len;
}
}catch(e){};
return { start:s, end:e };
}
config.macros.search.setCursorPos=function(i,pos) {
if (!i||!pos) return; var s=pos.start; var e=pos.end;
if (i.setSelectionRange) //FF
i.setSelectionRange(s,e);
if (i.createTextRange) // IE
{ var r=i.createTextRange(); r.collapse(true); r.moveStart("character",s); r.select(); }
}
//}}}
// // SearchResults report generation
// note: these functions are defined globally, so they can be more easily redefined to customize report formats//
//{{{
if (!window.reportSearchResults) window.reportSearchResults=function(text,matches)
{
var cms=config.macros.search; // abbrev
var body=window.formatSearchResults(text,matches);
if (!config.options.chkSearchListTiddler) // show #searchResults panel
window.scrollTo(0,ensureVisible(cms.createPanel(text,matches,body)));
else { // write [[SearchResults]] tiddler
var title=cms.reportTitle;
var who=config.options.txtUserName;
var when=new Date();
var tags="excludeLists excludeSearch temporary";
var tid=store.getTiddler(title); if (!tid) tid=new Tiddler();
tid.set(title,body,who,when,tags);
store.addTiddler(tid);
story.closeTiddler(title);
story.displayTiddler(null,title);
}
}
if (!window.formatSearchResults) window.formatSearchResults=function(text,matches,opt)
{
var body='';
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
if (!opt) var opt="all";
var parts=opt.split("+");
for (var i=0; i<parts.length; i++) { var p=parts[i].toLowerCase();
if (p=="again"||p=="all") body+=window.formatSearchResults_again(text,matches);
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);
}
return body;
}
if (!window.formatSearchResults_again) window.formatSearchResults_again=function(text,matches)
{
var title=config.macros.search.reportTitle
var body='';
// search again
body+='{{span{<<search "'+text.replace(/"/g,'"')+'">> /%\n';
body+='%/<html><input type="button" value="search again"';
body+=' onclick="var t=this.parentNode.parentNode.getElementsByTagName(\'input\')[0];';
body+=' config.macros.search.doSearch(t); return false;">';
body+=' <a href="javascript:;" onclick="';
body+=' var e=this.parentNode.nextSibling;';
body+=' var show=e.style.display!=\'block\';';
body+=' if(!config.options.chkAnimate) e.style.display=show?\'block\':\'none\';';
body+=' else anim.startAnimating(new Slider(e,show,false,\'none\'));';
body+=' return false;">options...</a>';
body+='</html>@@display:none;border-left:1px dotted;margin-left:1em;padding:0;padding-left:.5em;font-size:90%;/%\n';
body+=' %/<<option chkSearchTitles>>titles /%\n';
body+=' %/<<option chkSearchText>>text /%\n';
body+=' %/<<option chkSearchTags>>tags /%\n';
body+=' %/<<option chkSearchFields>>fields /%\n';
body+=' %/<<option chkSearchShadows>>shadows\n';
body+=' <<option chkCaseSensitiveSearch>>case-sensitive /%\n';
body+=' %/<<option chkRegExpSearch>>text patterns /%\n';
body+=' %/<<option chkSearchByDate>>sorted by date\n';
body+=' <<option chkSearchHighlight>> highlight matching text in displayed tiddlers\n';
body+=' <<option chkIncrementalSearch>>incremental key-by-key search: /%\n';
body+=' %/{{twochar{<<option txtIncrementalSearchMin>>}}} or more characters, /%\n';
body+=' %/{{threechar{<<option txtIncrementalSearchDelay>>}}} msec delay\n';
body+=' <<option chkSearchOpenTiddlers>> search only in tiddlers that are currently displayed\n';
body+=' <<option chkSearchExcludeTags>>exclude tiddlers tagged with:\n';
body+=' {{editor{<<option txtSearchExcludeTags>>}}}/%\n';
body+='%/@@}}}\n\n';
return body;
}
if (!window.formatSearchResults_summary) window.formatSearchResults_summary=function(text,matches)
{
// summary: nn tiddlers found matching '...', options used
var body='';
var co=config.options; // abbrev
var title=config.macros.search.reportTitle
var q = co.chkRegExpSearch ? "/" : "'";
body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\n";
var opts=[];
if (co.chkSearchTitles) opts.push("titles");
if (co.chkSearchText) opts.push("text");
if (co.chkSearchTags) opts.push("tags");
if (co.chkSearchFields) opts.push("fields");
if (co.chkSearchShadows) opts.push("shadows");
if (co.chkSearchOpenTiddlers) body+="^^//search limited to displayed tiddlers only//^^\n";
body+="~~ searched in "+opts.join(" + ")+"~~\n";
body+=(co.chkCaseSensitiveSearch||co.chkRegExpSearch?"^^ using ":"")
+(co.chkCaseSensitiveSearch?"case-sensitive ":"")
+(co.chkRegExpSearch?"pattern ":"")
+(co.chkCaseSensitiveSearch||co.chkRegExpSearch?"matching^^\n":"");
return body;
}
if (!window.formatSearchResults_list) window.formatSearchResults_list=function(text,matches)
{
// bullet list of links to matching tiddlers
var body='';
var pattern=co.chkRegExpSearch?text:text.escapeRegExp();
var sensitive=co.chkCaseSensitiveSearch?"mg":"img";
var link='{{tiddlyLinkExisting{<html><nowiki><a href="javascript:;" onclick="'
+'if(config.options.chkSearchHighlight)'
+' highlightHack=new RegExp(\x27'+pattern+'\x27,\x27'+sensitive+'\x27);'
+'story.displayTiddler(null,\x27%0\x27);'
+'highlightHack = null; return false;'
+'" title="%2">%1</a></html>}}}';
for(var t=0;t<matches.length;t++) {
body+="* ";
if (config.options.chkSearchByDate)
body+=matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" ";
var title=matches[t].title;
var fixup=title.replace(/'/g,"\\x27").replace(/"/g,"\\x22");
var tid=store.getTiddler(title);
var tip=tid?tid.getSubtitle():''; tip=tip.replace(/"/g,""");
body+=link.format([fixup,title,tip])+'\n';
}
return body;
}
if (!window.formatSearchResults_buttons) window.formatSearchResults_buttons=function(text,matches)
{
// embed buttons only if writing SearchResults to tiddler
if (!config.options.chkSearchListTiddler) return "";
// "open all" button
var title=config.macros.search.reportTitle;
var body="";
body+="@@diplay:block;<html><input type=\"button\" href=\"javascript:;\" "
+"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 SearchResults" button
body+="<html><input type=\"button\" href=\"javascript:;\" "
+"onclick=\"discardSearchResults()\" value=\"discard "+title+"\"></html>";
body+="@@\n";
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|ShowPopup|
|Source|http://www.TiddlyTools.com/#ShowPopup|
|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|transcluded html|
|Requires||
|Overrides||
|Description|display tiddler content in a TW popup|
usage: <<tiddler ShowPopup with: TiddlerName label tooltip buttonClass width popupClass>>
%/<html><a href="javascript:;" class="$4" title="$3" onclick="var p=Popup.create(this); if (!p) return; var t=store.getTiddlerText('$1'); if (!t) return; p.className+=' $6'; var d=createTiddlyElement(p,'div'); d.style.whiteSpace='normal'; d.style.width='$5'; d.style.padding='2px'; wikify(t,d); Popup.show(p,false); event.cancelBubble = true; if (event.stopPropagation) event.stopPropagation(); return(false);">$2</a></html>
<<closeAll>>/%
%/<<permaview>>/%
%/<<newTiddler>>/%
%/<<newJournal "DD MMM YYYY" "journal">>/%
%/<<saveChanges>>/%
%/{{span{<<saveAs>><script>
place.style.display=(document.location.protocol!='file:')?'none':'inline';
</script>}}}/%
%/<<tiddler TspotSidebar>>/%
%/<<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>
/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.6|
|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.displayTiddler(), Story.prototype.displayTiddlers()|
|Options|##Configuration|
|Description|Show tiddlers one at a time with automatic permalink, or always open tiddlers at top/bottom of page.|
This plugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one tiddler displayed at a time.
!!!!!Documentation
>see [[SinglePageModePluginInfo]]
!!!!!Configuration
<<<
<<option chkSinglePageMode>> Display one tiddler at a time
><<option chkSinglePagePermalink>> Automatically permalink current tiddler
><<option chkSinglePageKeepFoldedTiddlers>> Don't close tiddlers that are folded
><<option chkSinglePageKeepEditedTiddlers>> Don't close tiddlers that are being edited
<<option chkTopOfPageMode>> Open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Open tiddlers at the bottom of the page
<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed)
Notes:
* The "display one tiddler at a time" option can also be //temporarily// set/reset by including a 'paramifier' in the document URL: {{{#SPM:true}}} or {{{#SPM:false}}}.
* If more than one display mode is selected, 'one at a time' display takes precedence over both 'top' and 'bottom' settings, and if 'one at a time' setting is not used, 'top of page' takes precedence over 'bottom of page'.
* When using Apple's Safari browser, automatically setting the permalink causes an error and is disabled.
<<<
!!!!!Revisions
<<<
2008.10.17 [2.9.6] changed chkSinglePageAutoScroll default to false
| Please see [[SinglePageModePluginInfo]] for previous revision details |
2005.08.15 [1.0.0] Initial Release. Support for BACK/FORWARD buttons adapted from code developed by Clint Checketts.
<<<
!!!!!Code
***/
//{{{
version.extensions.SinglePageModePlugin= {major: 2, minor: 9, revision: 6, date: new Date(2008,10,17)};
//}}}
//{{{
config.paramifiers.SPM = { onstart: function(v) {
config.options.chkSinglePageMode=eval(v);
if (config.options.chkSinglePageMode && config.options.chkSinglePagePermalink && !config.browser.isSafari) {
config.lastURL = window.location.hash;
if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
}
} };
//}}}
//{{{
if (config.options.chkSinglePageMode==undefined)
config.options.chkSinglePageMode=false;
if (config.options.chkSinglePagePermalink==undefined)
config.options.chkSinglePagePermalink=true;
if (config.options.chkSinglePageKeepFoldedTiddlers==undefined)
config.options.chkSinglePageKeepFoldedTiddlers=false;
if (config.options.chkSinglePageKeepEditedTiddlers==undefined)
config.options.chkSinglePageKeepEditedTiddlers=false;
if (config.options.chkTopOfPageMode==undefined)
config.options.chkTopOfPageMode=false;
if (config.options.chkBottomOfPageMode==undefined)
config.options.chkBottomOfPageMode=false;
if (config.options.chkSinglePageAutoScroll==undefined)
config.options.chkSinglePageAutoScroll=false;
//}}}
//{{{
config.SPMTimer = 0;
config.lastURL = window.location.hash;
function checkLastURL()
{
if (!config.options.chkSinglePageMode)
{ window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }
if (config.lastURL == window.location.hash) return; // no change in hash
var tids=decodeURIComponent(window.location.hash.substr(1)).readBracketedList();
if (tids.length==1) // permalink (single tiddler in URL)
story.displayTiddler(null,tids[0]);
else { // restore permaview or default view
config.lastURL = window.location.hash;
if (!tids.length) tids=store.getTiddlerText("DefaultTiddlers").readBracketedList();
story.closeAllTiddlers();
story.displayTiddlers(null,tids);
}
}
if (Story.prototype.SPM_coreDisplayTiddler==undefined)
Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,slowly)
{
var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
var tiddlerElem=document.getElementById(story.idPrefix+title); // ==null unless tiddler is already displayed
var opt=config.options;
var single=opt.chkSinglePageMode && !startingUp;
var top=opt.chkTopOfPageMode && !startingUp;
var bottom=opt.chkBottomOfPageMode && !startingUp;
if (single) {
story.forEachTiddler(function(tid,elem) {
// skip current tiddler and, optionally, tiddlers that are folded.
if ( tid==title
|| (opt.chkSinglePageKeepFoldedTiddlers && elem.getAttribute("folded")=="true"))
return;
// if a tiddler is being edited, ask before closing
if (elem.getAttribute("dirty")=="true") {
if (opt.chkSinglePageKeepEditedTiddlers) return;
// if tiddler to be displayed is already shown, then leave active tiddler editor as is
// (occurs when switching between view and edit modes)
if (tiddlerElem) return;
// otherwise, ask for permission
var msg="'"+tid+"' is currently being edited.\n\n";
msg+="Press OK to save and close this tiddler\nor press Cancel to leave it opened";
if (!confirm(msg)) return; else story.saveTiddler(tid);
}
story.closeTiddler(tid);
});
}
else if (top)
arguments[0]=null;
else if (bottom)
arguments[0]="bottom";
if (single && opt.chkSinglePagePermalink && !config.browser.isSafari) {
window.location.hash = encodeURIComponent(String.encodeTiddlyLink(title));
config.lastURL = window.location.hash;
document.title = wikifyPlain("SiteTitle") + " - " + title;
if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
}
if (tiddlerElem && tiddlerElem.getAttribute("dirty")=="true") { // editing... move tiddler without re-rendering
var isTopTiddler=(tiddlerElem.previousSibling==null);
if (!isTopTiddler && (single || top))
tiddlerElem.parentNode.insertBefore(tiddlerElem,tiddlerElem.parentNode.firstChild);
else if (bottom)
tiddlerElem.parentNode.insertBefore(tiddlerElem,null);
else this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
} else
this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
var tiddlerElem=document.getElementById(story.idPrefix+title);
if (tiddlerElem&&opt.chkSinglePageAutoScroll) {
// scroll to top of page or top of tiddler
var isTopTiddler=(tiddlerElem.previousSibling==null);
var yPos=isTopTiddler?0:ensureVisible(tiddlerElem);
// if animating, defer scroll until after animation completes
var delay=opt.chkAnimate?config.animDuration+10:0;
setTimeout("window.scrollTo(0,"+yPos+")",delay);
}
}
if (Story.prototype.SPM_coreDisplayTiddlers==undefined)
Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;
Story.prototype.displayTiddlers = function() {
// suspend single/top/bottom modes when showing multiple tiddlers
var opt=config.options;
var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
this.SPM_coreDisplayTiddlers.apply(this,arguments);
opt.chkBottomOfPageMode=saveBPM;
opt.chkTopOfPageMode=saveTPM;
opt.chkSinglePageMode=saveSPM;
}
//}}}
{{floatright small{<<tiddler BreadcrumbsCommand with: crumbs>><<tiddler ToggleBreadcrumbs>>}}}{{small{
Goto/Search:
{{transparent{<<gotoTiddler
inputstyle:"width:97%;font-size:100%;border:2px inset #999;"
liststyle:"width:97%;font-size:100%;"
search
>>}}}}}}
Great things are not done by impulse, but by a series of small things brought together. [Vincent van Gogh]
----
If we knew what it was we were doing, it would not be called research, would it? [Albert Einstein]
----
To invent, you need a good imagination and a pile of junk. [Thomas Edison]
----
Dare to be naive. [R. Buckminster Fuller]
----
Only half of writing is saying what you mean. The other half is preventing people from reading what they expected you to mean. [James Richardson, 'Ploughshares']
----
On two occasions I have been asked (by members of Parliament!), 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. [Charles Babbage]
----
Those parts of the system that you can hit with a hammer (not advised) are called hardware; those program instructions that you can only curse at are called software.
----
In the design of sophisticated digital systems, elegance is not a dispensable luxury but a matter of life and death, being a major factor that decides between success and failure. [Edsger W. Dijkstra]
----
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies, and the other way to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. [Charles A. R. Hoare]
----
The way to learn to use TiddlyWiki is to forget that you don't know how to use TiddlyWiki... [Eric Shulman]
{{medium{
//"[[Does this taste right to you?]]"//
}}}{{small{
}}}
{{floatleft italic{@@font-family:Trebuchet MS;[[LumpyMilk|http://lumpymilk.tiddlyspot.com/index.html]]@@ }}}
/***
|Name|SnapshotPlugin|
|Source|http://www.TiddlyTools.com/#SnapshotPlugin|
|Documentation|http://www.TiddlyTools.com/#SnapshotPluginInfo|
|Version|1.1.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|save or print HTML+CSS image of rendered document content|
|Status|ALPHA - DO NOT DISTRIBUTE|
This plugin provides a macro as well as tiddler toolbar commands to create a file or browser window containing the //rendered// CSS-and-HTML that is currently being displayed for selected elements of the current document.
!!!!!Documentation
>see [[SnapshotPluginInfo]]
!!!!!Configuration
<<<
<<option chkSnapshotHTMLOnly>> output HTML only (omit CSS)
<<<
!!!!!Revisions
<<<
2008.05.16 [1.1.1] added try..catch around addEvent/removeEvent calls to avoid error in Opera
2008.04.28 [1.1.0] removed 'viewerHTML' from 'ask' droplist and replaced with toggle for "output HTML only". Removed 'noCSS' parameter and replaced with config.options.chkSnapshotHTMLOnly global option. Added "select a tiddler..." to 'ask' droplist
2008.04.24 [1.0.1] in saveSnap(), convert output from Unicode to UTF before passing to saveFile(). Fixes "unknown name" error in IE's file.Write() function. Added viewerHTML to 'ask' droplist.
2008.04.21 [1.0.0] initial release - derived from [[NewDocumentPlugin]] with many improvements, including: "ask for ID" using droplist of available DOM elements, use "<base href=...>" for correctly resolving image references, wrap 'viewer only' output in class="tiddler viewer" for proper application of inherited CSS styles, snapshotSave and snapshotPrint tiddler toolbar command definitions, and more...
<<<
!!!!!Code
***/
//{{{
version.extensions.SnapshotPlugin= {major: 1, minor: 1, revision: 1, date: new Date(2008,5,16)};
if (config.options.chkSnapshotHTMLOnly===undefined) config.options.chkSnapshotHTMLOnly=false;
config.macros.snapshot = {
snapLabel: "save a snapshot",
printLabel: "print a snapshot",
snapPrompt: "save an HTML image of rendered content",
printPrompt: "print an HTML image of rendered content",
hereID: "here",
viewerID: "viewer",
storyID: "story",
allID: "all",
askID: "ask",
askTiddlerID: "askTiddler",
askDOMID: "askDOM",
askMsg: "select an element...",
hereItem: "tiddler: '%0'",
viewerItem: "tiddler: '%0' (content only)",
storyItem: "story column",
allItem: "entire document",
tiddlerItem: "select a tiddler...",
IDItem: "select a DOM element by ID...",
HTMLItem: "[%0] output HTML only (omit CSS)",
fileMsg: "select or enter a target path/filename",
defaultFilename: "snapshot.html",
okmsg: "snapshot written to %0",
failmsg: "An error occurred while creating %0",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var printing=params[0]&¶ms[0]=="print"; if (printing) params.shift();
params = paramString.parseParams("anon",null,true,false,false);
var id=getParam(params,"id","here");
var label=getParam(params,"label",printing?this.printLabel:this.snapLabel);
var prompt=getParam(params,"prompt",printing?this.printPrompt:this.snapPrompt);
var btn=createTiddlyButton(place,label,prompt, function(ev){
this.setAttribute("snapID",this.getAttribute("startID"));
config.macros.snapshot.go(this,ev)
});
btn.setAttribute("startID",id);
btn.setAttribute("snapID",id);
btn.setAttribute("printing",printing?"true":"false");
btn.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
},
go: function(here,ev) {
var cms=config.macros.snapshot; // abbreviation
var id=here.getAttribute("snapID");
var printing=here.getAttribute("printing")=="true";
var HTMLOnly=here.getAttribute("HTMLOnly")=="true";
if (id==cms.askID||id==cms.askTiddlerID||id==cms.askDOMID) {
cms.askForID(here,ev);
} else {
// get element
if (id==cms.storyID) id="tiddlerDisplay";
if (id==cms.allID) id="contentWrapper";
var snapElem=document.getElementById(id);
if (id==cms.hereID || id==cms.viewerID)
var snapElem=story.findContainingTiddler(here);
if (snapElem && hasClass(snapElem,"tiddler") && (id==cms.viewerID || HTMLOnly)) {
// find viewer class element within tiddler element
var nodes=snapElem.getElementsByTagName("*");
for (var i=0; i<nodes.length; i++)
if (hasClass(nodes[i],"viewer")) { snapElem=nodes[i]; break; }
}
if (!snapElem) // not in a tiddler or no viewer element or unknown ID
{ e.cancelBubble=true; if(e.stopPropagation)e.stopPropagation(); return(false); }
// write or print snapshot
var out=cms.getsnap(snapElem,id,printing,HTMLOnly);
if (printing) cms.printsnap(out); else cms.savesnap(out);
}
return false;
},
askForID: function(here,ev) {
var ev = ev ? ev : window.event;
var cms=config.macros.snapshot; // abbreviation
var id=here.getAttribute("snapID");
var indent='\xa0\xa0\xa0\xa0';
var p=Popup.create(here); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=here;
if (id==cms.askID) {
s.options[s.length]=new Option(cms.askMsg,cms.askID);
var tid=story.findContainingTiddler(here);
if(tid) {
var title=tid.getAttribute("tiddler");
if (here.getAttribute("HTMLOnly")!="true")
s.options[s.length]=new Option(indent+cms.hereItem.format([title]),cms.hereID);
s.options[s.length]=new Option(indent+cms.viewerItem.format([title]),cms.viewerID);
}
s.options[s.length]=new Option(indent+cms.tiddlerItem,cms.askTiddlerID);
s.options[s.length]=new Option(indent+cms.IDItem,cms.askDOMID);
s.options[s.length]=new Option(indent+cms.storyItem,"tiddlerDisplay");
s.options[s.length]=new Option(indent+cms.allItem,"contentWrapper");
}
if (id==cms.askDOMID) {
s.options[s.length]=new Option(cms.IDItem,cms.askDOMID);
var elems=document.getElementsByTagName("*");
var ids=[];
for (var i=0;i<elems.length;i++)
if (elems[i].id.length && elems[i].className!="animationContainer")
ids.push(elems[i].id);
ids.sort();
for (var i=0;i<ids.length;i++) s.options[s.length]=new Option(indent+ids[i],ids[i]);
}
if (id==cms.askTiddlerID) {
s.options[s.length]=new Option(cms.tiddlerItem,cms.askTiddlerID);
var elems=document.getElementsByTagName("div");
var ids=[];
for (var i=0;i<elems.length;i++) { var id=elems[i].id;
if (id.length && id.substr(0,story.idPrefix.length)==story.idPrefix && id!="tiddlerDisplay")
ids.push(id);
}
ids.sort();
for (var i=0;i<ids.length;i++) s.options[s.length]=new Option(indent+ids[i].substr(story.idPrefix.length),ids[i]);
}
s.options[s.length]=new Option(cms.HTMLItem.format([here.getAttribute("HTMLOnly")=="true"?"\u221a":"_"]),cms.HTMLItem);
s.onchange=function(ev){
var ev = ev ? ev : window.event;
var cms=config.macros.snapshot; // abbreviation
var here=this.button;
if (this.value==cms.HTMLItem) {
config.options.chkSnapshotHTMLOnly=!config.options.chkSnapshotHTMLOnly;
here.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
config.macros.option.propagateOption("chkSnapshotHTMLOnly","checked",
config.options.chkSnapshotHTMLOnly,"input");
} else
here.setAttribute("snapID",this.value);
config.macros.snapshot.go(here,ev);
return false;
};
Popup.show(p,false);
ev.cancelBubble=true;
if(ev.stopPropagation)ev.stopPropagation();
return false;
},
getpath: function() {
// get current path
var path=getLocalPath(window.location.href);
var slashpos=path.lastIndexOf("/");
if (slashpos==-1) slashpos=path.lastIndexOf("\\");
if (slashpos!=-1) path=path.substr(0,slashpos+1); // trim filename
return path;
},
getsnap: function(snapElem,id,printing,HTMLOnly) {
var cms=config.macros.snapshot; // abbreviation
var out="";
out+="<html><head>\n";
if (printing)
out+='<base href="file:///'+cms.getpath().replace(/\\/g,'/')+'"></base>\n';
if (!HTMLOnly) {
var styles=document.getElementsByTagName("style");
for(var i=0; i < styles.length; i++) {
out+="<style>\n";
out+="/* stylesheet="+styles[i].getAttribute("id")+" */\n";
out+=styles[i].innerHTML+"\n\n";
out+="</style>\n";
}
}
out+="</head><body>\n\n<div"+(id==cms.viewerID?" class='tiddler viewer'>":">");
out+=snapElem.innerHTML;
out+="</div>\n\n</body>\n";
out+="</html>";
return out;
},
printsnap: function(out) {
var win=window.open("","_blank","");
win.document.open();
win.document.writeln(out);
win.document.close();
win.focus(); // bring to front
win.print(); // trigger print dialog
},
savesnap: function(out) {
var cms=config.macros.snapshot; // abbreviation
// make sure we are local
if (window.location.protocol!="file:")
{ alert(config.messages.notFileUrlError); return; }
var target=cms.askForFilename(cms.fileMsg,cms.getpath(),cms.defaultFilename);
if (!target) return; // cancelled by user
// if specified file does not include a path, assemble fully qualified path and filename
var slashpos=target.lastIndexOf("/");
if (slashpos==-1) slashpos=target.lastIndexOf("\\");
if (slashpos==-1) target=target+cms.defaultFilename;
var link="file:///"+target.replace(/\\/g,'/'); // link for message text
var ok=saveFile(target,convertUnicodeToUTF8(out));
var msg=ok?cms.okmsg.format([target]):cms.failmsg.format([target]);
clearMessage(); displayMessage(msg,link);
},
askForFilename: function(msg,path,file) {
if(window.Components) { // moz
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='html';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
}
catch(e) { alert('error during local file access: '+e.toString()) }
}
else { // IE
try { // XP/Vista only
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
s.FilterIndex=3; // default to HTML files;
s.InitialDir=path;
s.FileName=file;
if (s.showOpen()) var result=s.FileName;
}
catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
}
return result;
}
};
//}}}
// // TOOLBAR DEFINITIONS
//{{{
config.commands.snapshotSave = {
text: "snap",
tooltip: config.macros.snapshot.snapPrompt,
handler: function(ev,src,title) {
src.setAttribute("snapID","ask");
src.setAttribute("printing","false");
src.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
config.macros.snapshot.go(src,ev);
return false;
}
};
config.commands.snapshotPrint = {
text: "print",
tooltip: config.macros.snapshot.printPrompt,
handler: function(ev,src,title) {
src.setAttribute("snapID","ask");
src.setAttribute("printing","true");
src.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
config.macros.snapshot.go(src,ev);
return false;
}
};
//}}}
// // COPIED FROM [[StickyPopupPlugin]] TO ELIMINATE PLUGIN DEPENDENCY
//{{{
if (config.options.chkStickyPopups==undefined) config.options.chkStickyPopups=false;
Popup.stickyPopup_onDocumentClick = function(ev)
{
// if click is in a sticky popup, ignore it so popup will remain visible
var e = ev ? ev : window.event; var target = resolveTarget(e);
var p=target; while (p) {
if (hasClass(p,"popup") && (hasClass(p,"sticky")||config.options.chkStickyPopups)) break;
else p=p.parentNode;
}
if (!p) // not in sticky popup (or sticky popups disabled)... use normal click handling
Popup.onDocumentClick(ev);
return true;
};
try{removeEvent(document,"click",Popup.onDocumentClick);}catch(e){};
try{addEvent(document,"click",Popup.stickyPopup_onDocumentClick);}catch(e){};
//}}}
{{center{
{{floatleft{<<tiddler ToggleLeftSidebar>>}}}{{floatright{<<tiddler ToggleRightSidebar>>}}}/%
%/{{small{
<<openStory popup>><script>place.lastChild.className='tiddlyLinkExisting';</script>/%
%/ <<tag journal entries>><script>place.lastChild.className='tiddlyLinkExisting';</script>/%
%/ <<tag bookmark bookmarks>><script>place.lastChild.className='tiddlyLinkExisting';</script>/%
%/ <<tiddler ShowPopup with:
[[StoryMenu##info]] "info" "About, Contact, Credits..." tiddlyLinkExisting auto>>/%
%/ <<tiddler ShowPopup with:
[[StoryMenu##changes]] "changes" "show recent changes" tiddlyLinkExisting 60em sticky>>/%
%/ <<tiddler ShowPopup with:
[[StoryMenu##calendar]] "calendar" "show this month" tiddlyLinkExisting auto sticky>>/%
%/ {{span{<script>
place.style.display=readOnly?'none':'inline';
</script><<tiddler ShowPopup with:
[[DocumentSetup]] "setup" "configuration and setup" tiddlyLinkExisting auto>>/%
%/}}}
{{smallform{<<unsavedChanges panel>>}}}/%
%/}}}/%
!info
[[about|Does this taste right to you?]]
[[contact|ContactTheAuthor]]
[[credits|Credits]]
!end
!changes
{{smallform{<<recentChanges 30>>}}}
!end
!calendar
{{normal{<<calendar thismonth>>}}}
!end
%/
/***
|Name|StorySaverPlugin|
|Source|http://www.TiddlyTools.com/#StorySaverPlugin|
|Documentation|http://www.TiddlyTools.com/#StorySaverPluginInfo|
|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|MarkupPostBody|
|Overrides|confirmExit(), getParameters()|
|Description|save/restore current tiddler view between browser sessions|
This plugin automatically saves a list of the currently viewed tiddlers (the "story") in a local cookie, {{{txtSavedStory}}} and then opens those tiddlers when the document is subsequently reloaded... the tiddlers you were viewing in the last browser session are automatically redisplayed in the next session, allowing you to quickly resume working with the document from the same place you left off!!
In addition to automatic cookie-based story tracking, the plugin also provides {{{<<saveStory>>}}} and {{{<<openStory>>}}} macros that allow you to quickly save the current story definition to a tiddler, and then re-display saved stories using simple, one-click command links or droplists.
!!!!!Documentation
>see [[StorySaverPluginInfo]]
!!!!!Revisions
<<<
2008.09.07 [1.4.3] added removeCookie() function for compatibility with [[CookieManagerPlugin]]
2008.07.11 [1.4.2] in confirmExit(), corrected bracketing for titles containing spaces
2008.03.10 [*.*.*] plugin size reduction: documentation moved to [[StorySaverPluginInfo]]
|please see [[StorySaverPluginInfo]] for additional revision details|
2007.10.05 [1.0.0] initial release. Moved [[SetDefaultTiddlers]] inline script and rewrote as a {{{<<saveStory>>}}} macro.
<<<
!!!!!Code
***/
//{{{
version.extensions.StorySaverPlugin= {major: 1, minor: 4, revision: 3, date: new Date(2008,9,7)};
//}}}
// // ''save or clear story cookie on exit:''
//{{{
// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
window.removeCookie=function(name) {
document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
}
}
if (config.options.chkSaveStory==undefined) config.options.chkSaveStory=false;
if (window.coreTweaks_confirmExit==undefined) {
window.coreTweaks_confirmExit=window.confirmExit;
window.confirmExit=function() {
if (config.options.chkSaveStory) { // save cookie
var links=[];
story.forEachTiddler(function(title,element){links.push('[['+title+']]');});
config.options.txtSavedStory=links.join(" ");
saveOptionCookie("txtSavedStory");
} else removeCookie("txtSavedStory");
return window.coreTweaks_confirmExit.apply(this,arguments);
}
}
//}}}
/***
''apply saved story on startup:'' //important note: the following code is actually located in [[MarkupPostBody]]. This is because it needs to supercede the core's getParameters() function, which is called BEFORE plugins are loaded, preventing the normal plugin-based hijack method from working, while code loaded into [[MarkupPostBody]] will be processed as soon as the document is read, even before the TW main() function is invoked.//
<<tiddler MarkupPostBody>>
***/
// // MACRO definitions
//{{{
config.macros.saveStory = {
label: "set default tiddlers",
defaultTiddler: "DefaultTiddlers",
prompt: "store a list of currently displayed tiddlers in another tiddler",
askMsg: "Enter the name of a tiddler in which to save the current story:",
tag: "story",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var tid=params[0]?params[0]:"DefaultTiddlers";
var label=params[1]?params[1]:this.label;
var tip=params[2]?params[2]:this.prompt;
var btn=createTiddlyButton(place,label,tip,this.setTiddler,"button");
btn.setAttribute("tid",tid);
},
setTiddler: function() {
// get list of current open tiddlers
var tids=[];
story.forEachTiddler(function(title,element){tids.push("[["+title+"]]")}); // always put titles in brackets
// get target tiddler
var tid=this.getAttribute("tid");
if (!tid || tid=="ask") {
tid=prompt(config.macros.saveStory.askMsg,config.macros.saveStory.defaultTiddler);
if (!tid || !tid.length) return; // cancelled by user
}
if(store.tiddlerExists(tid) && !confirm(config.messages.overwriteWarning.format([tid]))) return;
tids=tids.join("\n"); // separate tiddler links by newlines for easier reading
var t=store.getTiddler(tid); var tags=t?t.tags:[]; tags.push(config.macros.saveStory.tag);
store.saveTiddler(tid,tid,tids,config.options.txtUserName,new Date(),tags,t?t.fields:null);
story.displayTiddler(null,tid); story.refreshTiddler(tid,null,true);
displayMessage(tid+" has been "+(t?"updated":"created"));
}
}
//}}}
//{{{
if (config.options.chkStoryFold==undefined) config.options.chkStoryFold=true;
if (config.options.chkStoryClose==undefined) config.options.chkStoryClose=true;
config.macros.openStory = {
label: "open story: %0",
prompt: "open the set of tiddlers listed in: '%0'",
popuplabel: "stories",
popupprompt: "view a set of tiddlers",
tag: "story",
selectprompt: "select a story...",
optionsprompt: "viewing options...",
foldcmd: "[%0] fold story",
foldprompt: "fold story tiddlers when opening a story",
closecmd: "[%0] close others",
closeprompt: "close other tiddlers when opening a story",
addcmd: "add a story...",
addprompt: "create a new story",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
if (params[0].toLowerCase()=="list") return this.createList(place,params);
else if (params[0].toLowerCase()=="popup") return this.createPopup(place,params);
else this.createButton(place,params);
},
showStory: function(tid) {
var tids=[];
var tagged=store.getTaggedTiddlers(tid,"title");
if (tagged.length) // if tiddler IS a tag, use tagged tiddlers as story
for (var t=0; t<tagged.length; t++) tids.push(tagged[t].title);
else { // get tiddler list from content
var t=store.getTiddler(tid);
if (t) { if (!t.linksUpdated) t.changed(); tids=t.links; }
}
// see [[CollapseTiddlersPlugin]] for more info, re: folding tiddlers
var template=null;
if (config.options.chkStoryFold) template="CollapsedTemplate";
if (!store.tiddlerExists("CollapsedTemplate")) template=null;
if (config.options.chkStoryClose) story.closeAllTiddlers();
story.displayTiddlers(null,tids,template);
},
createButton: function(place,params) {
var tid=params[0]?params[0]:"";
var label=params[1]?params[1]:this.label; label=label.format([tid]);
var tip=params[2]?params[2]:this.prompt; tip=tip.format([tid]);
var fn=function(){config.macros.openStory.showStory(this.getAttribute("tid"))};
var btn=createTiddlyButton(place,label,tip,fn,"button");
btn.setAttribute("tid",tid);
},
createPopup: function(place,params) {
var label=params[1]?params[1]:this.popuplabel;
var tip=params[2]?params[2]:this.popupprompt;
var btn=createTiddlyButton(place,label,tip,this.showPopup,"button");
},
showPopup: function(ev) { var e=ev||window.event;
var indent="\xa0\xa0";
var p=Popup.create(this); if (!p) return false;
createTiddlyText(createTiddlyElement(p,"li"),config.macros.openStory.selectprompt);
var stories=store.getTaggedTiddlers("story","title");
for (var s=0; s<stories.length; s++) {
var label=indent+stories[s].title;
var tip=config.macros.openStory.prompt.format([stories[s].title]);
var fn=function(){config.macros.openStory.showStory(this.getAttribute("tid"))};
var btn=createTiddlyButton(createTiddlyElement(p,"li"),label,tip,fn,"button");
btn.setAttribute("tid",stories[s].title);
}
createTiddlyText(createTiddlyElement(p,"li"),config.macros.openStory.optionsprompt);
if (store.tiddlerExists("CollapsedTemplate")) {
var label=indent+config.macros.openStory.foldcmd.format([config.options.chkStoryFold?"x":"\xa0\xa0"]);
var tip=config.macros.openStory.foldprompt;
var fn=function(){config.options.chkStoryFold=!config.options.chkStoryFold;saveOptionCookie('chkStoryFold')};
var btn=createTiddlyButton(createTiddlyElement(p,"li"),label,tip,fn,"button");
}
var label=indent+config.macros.openStory.closecmd.format([config.options.chkStoryClose?"x":"\xa0\xa0"]);
var tip=indent+config.macros.openStory.closeprompt;
var fn=function(){config.options.chkStoryClose=!config.options.chkStoryClose;saveOptionCookie('chkStoryClose')};
var btn=createTiddlyButton(createTiddlyElement(p,"li"),label,tip,fn,"button");
if (!readOnly) {
var label=config.macros.openStory.addcmd;
var tip=config.macros.openStory.addprompt;
var fn=config.macros.saveStory.setTiddler;
createTiddlyElement(createTiddlyElement(p,"li"),"hr");
var btn=createTiddlyButton(createTiddlyElement(p,"li"),label,tip,fn,"button");
}
Popup.show(p,false);
e.cancelBubble=true;if(e.stopPropagation)e.stopPropagation();
return false;
},
createList: function(place,params) {
var s=createTiddlyElement(place,"select",null,"storyListbox");
s.size=1;
s.onchange=function() {
if (this.value=="_fold") {
config.options.chkStoryFold=!config.options.chkStoryFold; saveOptionCookie('chkStoryFold');
config.macros.openStory.refreshList();
} else if (this.value=="_close") {
config.options.chkStoryClose=!config.options.chkStoryClose; saveOptionCookie('chkStoryClose');
config.macros.openStory.refreshList();
} else if (this.value=="_add")
config.macros.saveStory.setTiddler.apply(this,arguments);
else config.macros.openStory.showStory(this.value);
}
setStylesheet(".storyListbox { width:100%; }", "StorySaverStyles");
store.addNotification(null,this.refreshList); this.refreshList();
return;
},
refreshList: function() {
var indent="\xa0\xa0\xa0\xa0";
var lists=document.getElementsByTagName("select");
for (var i=0; i<lists.length; i++) { if (lists[i].className!="storyListbox") continue;
var here=lists[i];
while (here.length) here.options[0]=null; // remove current list items
here.options[here.length]=new Option(config.macros.openStory.selectprompt,"",true,true);
var stories=store.getTaggedTiddlers("story","title");
for (var s=0; s<stories.length; s++)
here.options[here.length]=new Option(indent+stories[s].title,stories[s].title,false,false);
if (!readOnly)
here.options[here.length]=new Option(config.macros.openStory.addcmd,"_add",false,false);
here.options[here.length]=new Option(config.macros.openStory.optionsprompt,"",false,false);
if (store.tiddlerExists("CollapsedTemplate")) {
var msg=config.macros.openStory.foldcmd.format([config.options.chkStoryFold?"x":"\xa0\xa0"]);
here.options[here.length]=new Option(indent+msg,"_fold",false,false);
}
var msg=config.macros.openStory.closecmd.format([config.options.chkStoryClose?"x":"\xa0\xa0"]);
here.options[here.length]=new Option(indent+msg,"_close",false,false);
}
}
}
//}}}
data://image/gif;base64,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
/*{{{*/
/* SHORTCUTS */
[[StyleSheetShortcuts]]
/* ADJUSTMENTS TO SHORTCUTS */
.small { font-size:90%; line-height:120%; }
.fine { font-size:80%; line-height:120%; }
.tiny { font-size:70%; line-height:120%; }
.groupbox { padding:.5em; border:1px solid gray; -moz-border-radius:.5em; -webkit-border-radius:.5em; }
/* CUSTOM SHORTCUTS */
.scroll { display:block; overflow:auto; width:auto; max-height:12em; padding-bottom:.5em; }
.scroll ul { margin:0; }
.scroll li { white-space:nowrap; }
*[id="mainMenu"] .scroll li /* MOZ ONLY */ { margin-left:-2.5em; }
/* ADJUSTMENTS TO STANDARD ELEMENTS */
[[StyleSheetAdjustments]]
/* ADJUSTMENTS TO CUSTOM ELEMENTS */
.storyListbox { font-size:80%; }
.siteNav { position:absolute;z-index:1;right:.5em;top:2em;width:14em; }
.siteNav, .siteNav .button { color:#fff }
.siteNav .button:hover { color:#009 }
.siteNav input[type="checkbox"] { margin:0; }
.calendar td { background-color:#eee; }
.calendar td:hover { background-color:#fff !important; }
/* BACKGROUND COLORS/TEXTURES */
/* [[OFF_StyleSheetWood]]*/ [[StyleSheetStone]]
/*}}}*/
/*{{{*/
/* ADJUSTMENTS TO STANDARD ELEMENTS */
.headerShadow, .headerForeground
{ padding-top:1em; white-space:nowrap; }
#mainMenu
{ text-align:left; width:14em; padding:0.5em; }
#mainMenu table, #mainMenu table td
{ border:1px solid #999; border-collapse:collapse; padding:.3em; }
#displayArea
{ margin-left:16em; margin-right:15em; }
.popup
{ max-height:40em; overflow:auto; -moz-border-radius:.5em; -webkit-border-radius:.5em; padding:.5em; }
.popup li
{ white-space:nowrap; line-height:100%; }
.toolbar
{ float:right; white-space:nowrap; }
.viewer
{ border:1px solid gray; -moz-border-radius:.5em; -webkit-border-radius:.5em; padding:.5em; }
.tiddler .subtitle
{ display:none; }
.tagged
{ border:1px solid #999; -moz-border-radius:3px; -webkit-border-radius:3px; }
.tagged
{ opacity:.7; }
.selected .tagged
{ opacity:1; }
.button, .tiddler .button
{ margin:0px; padding: 0px .3em; border:1px solid transparent; -moz-border-radius:3px; -webkit-border-radius:3px; }
.button:hover
{ border:1px solid #999; }
.editor textarea
{ font-family:monospace; }
.tab
{
-moz-border-radius-topleft:.3em; -webkit-border-topleft-radius:.3em;
-moz-border-radius-topright:.3em; -webkit-border-topright-radius:.3em;
}
.tabContents
{ -moz-border-radius:.5em; -webkit-border-radius:.5em; }
/*}}}*/
/***
|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; }
.center table
{ margin:auto !important; }
.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;-webkit-border-radius:1em; border:1px solid; }
.menubox
{ display:block; padding:1em; -moz-border-radius:1em;-webkit-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;-webkit-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; }
/* scrolled content */
.scrollbars { overflow:auto; }
.height10em { height:10em; }
.height15em { height:15em; }
.height20em { height:20em; }
.height25em { height:25em; }
.height30em { height:30em; }
.height35em { height:35em; }
.height40em { height:40em; }
/* 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 */
.white { color:#fff !important }
.gray { color:#999 !important }
.black { color:#000 !important }
.red { color:#f66 !important }
.green { color:#0c0 !important }
.blue { color:#99f !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; }
/* [[ColorPalette]] text colors */
.Background { color:[[ColorPalette::Background]]; }
.Foreground { color:[[ColorPalette::Foreground]]; }
.PrimaryPale { color:[[ColorPalette::PrimaryPale]]; }
.PrimaryLight { color:[[ColorPalette::PrimaryLight]]; }
.PrimaryMid { color:[[ColorPalette::PrimaryMid]]; }
.PrimaryDark { color:[[ColorPalette::PrimaryDark]]; }
.SecondaryPale { color:[[ColorPalette::SecondaryPale]]; }
.SecondaryLight { color:[[ColorPalette::SecondaryLight]];}
.SecondaryMid { color:[[ColorPalette::SecondaryMid]]; }
.SecondaryDark { color:[[ColorPalette::SecondaryDark]]; }
.TertiaryPale { color:[[ColorPalette::TertiaryPale]]; }
.TertiaryLight { color:[[ColorPalette::TertiaryLight]]; }
.TertiaryMid { color:[[ColorPalette::TertiaryMid]]; }
.TertiaryDark { color:[[ColorPalette::TertiaryDark]]; }
.Error { color:[[ColorPalette::Error]]; }
/* [[ColorPalette]] background colors */
.BGBackground { background-color:[[ColorPalette::Background]]; }
.BGForeground { background-color:[[ColorPalette::Foreground]]; }
.BGPrimaryPale { background-color:[[ColorPalette::PrimaryPale]]; }
.BGPrimaryLight { background-color:[[ColorPalette::PrimaryLight]]; }
.BGPrimaryMid { background-color:[[ColorPalette::PrimaryMid]]; }
.BGPrimaryDark { background-color:[[ColorPalette::PrimaryDark]]; }
.BGSecondaryPale { background-color:[[ColorPalette::SecondaryPale]]; }
.BGSecondaryLight { background-color:[[ColorPalette::SecondaryLight]]; }
.BGSecondaryMid { background-color:[[ColorPalette::SecondaryMid]]; }
.BGSecondaryDark { background-color:[[ColorPalette::SecondaryDark]]; }
.BGTertiaryPale { background-color:[[ColorPalette::TertiaryPale]]; }
.BGTertiaryLight { background-color:[[ColorPalette::TertiaryLight]]; }
.BGTertiaryMid { background-color:[[ColorPalette::TertiaryMid]]; }
.BGTertiaryDark { background-color:[[ColorPalette::TertiaryDark]]; }
.BGError { background-color:[[ColorPalette::Error]]; }
/*}}}*/
/*{{{*/
.header
{ background-image: url('[[Stucco]]'); background-color:#f8f8f8; }
.headerForeground .siteSubtitle
{ color:#ccc; }
body
{ background-image: url('[[Stucco]]'); background-color:#f8f8f8; }
.viewer
{ background-image: url('[[CrumpledPaper]]'); background-color:#ffe; }
.viewer pre
{ border:1px solid; background-color:#ffe; }
.groupbox, .tabContents
{ background-image: url('[[ParchmentGray]]'); background-color:#fff; }
.siteNav, .siteNav .button
{ color:#000; }
.siteNav .button:hover
{ color:#009; }
.toolbar
{color:[[ColorPalette::TertiaryMid]];}
.toolbar a
{color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a
{color:[[ColorPalette::Foreground]];}
.selected .toolbar a:hover
{color:[[ColorPalette::PrimaryDark]];}
.transparent, .transparent input, .transparent textarea, .transparent select
{ background-color:transparent; }
.siteNav .transparent select
{ background-color:white; }
/*}}}*/
/*{{{*/
/* BACKGROUND TEXTURES */
.header
{ background-image: url('[[WoodDark]]'); background-color:#f8f8f8; }
.headerForeground a
{ color:#edb; }
body
{ background-image: url('[[WoodMedium]]'); background-color:#f8f8f8; }
.viewer
{ background-image: url('[[CrumpledPaper]]'); background-color:#ffe; }
.viewer pre
{ border:1px solid; background-color:#ffe; }
.groupbox
{ background-image: url('[[WoodLight]]'); background-color:#fff; }
.siteNav, .siteNav .button
{ color:#fff }
.siteNav .button:hover
{ color:#009 }
.toolbar {color:[[ColorPalette::TertiaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a {color:[[ColorPalette::Foreground]];}
.selected .toolbar a:hover {color:[[ColorPalette::PrimaryDark]];}
/*}}}*/
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.5.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.''
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2009.01.06 [1.5.1] reversed logic so that title-as-prefix takes precedence over tag-matched prefix
2008.12.18 [1.5.0] added handling for using tiddler //title// as prefix (e.g., {{{SomeTiddlerViewTemplate}}})
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TaggedTemplateTweak= {major: 1, minor: 5, revision: 1, date: new Date(2009,1,6)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
// get default template from core
var coreTemplate=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);
// if the tiddler doesn't exist yet, return core result
var tiddler=store.getTiddler(title); if (!tiddler) return coreTemplate;
// split core template into theme prefix and template name
var theme="";
var template=coreTemplate;
var parts=template.split(config.textPrimitives.sectionSeparator);
if (parts[1]) { theme=parts[0]; template=parts[1]; }
else theme=config.options.txtTheme||""; // fallback if theme is not specified
theme+=config.textPrimitives.sectionSeparator;
// look for template whose prefix matches the *title* of this tiddler
if (!store.getTaggedTiddlers(title).length) { // if tiddler is not a tag
if (store.getTiddlerText(theme+title+template)) { return theme+title+template; } // theme##TitleTemplate
if (store.getTiddlerText(title+template)) { return title+template; } // TitleTemplate
}
// look for template whose prefix matches a *tag* on this tiddler (if any)
for (i=0; i<tiddler.tags.length; i++) {
var t=tiddler.tags[i]+template; // add tag prefix to template
var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
if (store.getTiddlerText(theme+t)) { return theme+t; } // theme##tagTemplate
if (store.getTiddlerText(theme+c)) { return theme+c; } // theme##TagTemplate
if (store.getTiddlerText(t)) { return t; } // tagTemplate
if (store.getTiddlerText(c)) { return c; } // TagTemplate
}
// no matching tag OR title prefix... return core result
return coreTemplate;
}
//}}}
/***
|Name|TextAreaPlugin|
|Source|http://www.TiddlyTools.com/#TextAreaPlugin|
|Documentation|http://www.TiddlyTools.com/#TextAreaPluginInfo|
|Version|2.1.9|
|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.focusTiddler|
|Options|##Configuration|
|Description|Adds Find/Again keyboard search, autosize, and 'stretch bar' resize for textarea controls|
* ''Control-F'' and ''control-G'' will ''"Find text"'' and ''"find text aGain"'', respectively, allowing you to copy, find, paste, findagain, paste, etc to perform "search-and-replace" actions.
* ''autosizeEditor'' - toggles the tiddler editor textarea height between fixed-height and "automatically fit the contents".
* ''resizeEditor'' - adds 'grab handle' below textarea to stretch field height
!!!!!Documentation
>see [[TextAreaPluginInfo]]
!!!!!Configuration
<<<
<<option chkTextAreaExtensions>> use control-f (find), control-g (find again) inside text area
<<option chkDisableAutoSelect>> place cursor at start of textarea instead of pre-selecting content
<<option chkResizeEditor>> modify shadow EditTemplate to add resizeable text area (and autosize command)
<<<
!!!!!Revisions
<<<
2008.01.08 [2.1.9] fixed default setting of uninitialized option values so that "false" is not treated as "undefined"
|please see [[TextAreaPluginInfo]] for additional revision details|
2006.01.22 [1.0.0] Moved from temporary "System Tweaks" tiddler into 'real' TextAreaPlugin tiddler.
<<<
!!!!!Code
***/
//{{{
version.extensions.TextAreaPlugin= {major: 2, minor: 1, revision: 9, date: new Date(2008,1,8)};
if (config.options.chkTextAreaExtensions===undefined) config.options.chkTextAreaExtensions=true;
if (config.options.chkDisableAutoSelect===undefined) config.options.chkDisableAutoSelect=true;
if (config.options.chkResizeEditor===undefined) config.options.chkResizeEditor=true;
// automatically tweak shadow EditTemplate to add "autosizeEditor" toolbar command
if (config.options.chkResizeEditor)
config.shadowTiddlers.EditTemplate=config.shadowTiddlers.EditTemplate.replace(/deleteTiddler/,"deleteTiddler autosizeEditor");
// automatically tweak shadow EditTemplate to add "resizeEditor" macro
if (config.options.chkResizeEditor)
config.shadowTiddlers.EditTemplate+="<span macro='resizeEditor'></span>";
// Put focus in a specified tiddler field
Story.prototype.TextAreaExtensions_focusTiddler=Story.prototype.focusTiddler;
Story.prototype.focusTiddler = function(title,field)
{
this.TextAreaExtensions_focusTiddler.apply(this,arguments); // first call core
var e = this.getTiddlerField(title,field);
if (e && config.options.chkDisableAutoSelect) {
if (e.setSelectionRange) // FF
e.setSelectionRange(0,0);
else if (e.createTextRange) // IE
{ var r=e.createTextRange(); r.collapse(true); r.select(); }
}
if (e && config.options.chkTextAreaExtensions) addKeyDownHandlers(e);
}
//}}}
//{{{
function addKeyDownHandlers(e)
{
// exit if not textarea or element doesn't allow selections
if (e.tagName.toLowerCase()!="textarea"||!e.setSelectionRange||e.initialized) return;
// utility function: exits keydown handler and prevents browser from processing the keystroke
var processed=function(ev) {
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;
}
// capture keydown in edit field
e.saved_onkeydown=e.onkeydown; // save current keydown handler (if any)
e.onkeydown=function(ev) { if (!ev) var ev=window.event;
var key=ev.keyCode;
if (!key) {
var char=event.which?event.which:event.charCode;
if (char==102) key=70;
if (char==103) key=71;
}
// process CTRL-F (find matching text) or CTRL-G (find next match)
if (ev.ctrlKey && (key==70||key==71)) {
// prompt for text to find
var defFind=e.findText?e.findText:e.value.substring(e.selectionStart,e.selectionEnd);
if (key==70||!e.findText||!e.findText.length) // ctrl-f or no saved search text
{ var f=prompt("find:", defFind); e.focus(); if (f) e.findText=f; }
if (!e.findText||!e.findText.length) return processed(ev); // if no search text, exit
// do case-insensitive match with 'wraparound'... if not found, alert and exit
var newstart=e.value.toLowerCase().indexOf(e.findText.toLowerCase(),e.selectionStart+1);
if (newstart==-1) newstart=e.value.toLowerCase().indexOf(e.findText.toLowerCase());
if (newstart==-1) { alert("'"+e.findText+"' not found"); e.focus(); return processed(ev); }
// set new selection, scroll it into view, and report line position in status bar
e.setSelectionRange(newstart,newstart+e.findText.length);
var linecount=e.value.split('\n').length;
var thisline=e.value.substr(0,e.selectionStart).split('\n').length;
e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);
window.status="line: "+thisline+"/"+linecount;
return processed(ev);
}
if (e.saved_onkeydown) // call previous keydown handler (if any)
e.saved_onkeydown(ev);
}
e.initialized=true;
}
//}}}
// // 'autosize' toolbar command
//{{{
config.commands.autosizeEditor = {
text: 'autosize',
tooltip: 'automatically adjust the editor height to fit the contents',
text_alt: '\u221Aautosize',
hideReadOnly: false,
handler: function(event,src,title) {
var here=story.findContainingTiddler(src); if (!here) return;
var ta=here.getElementsByTagName('textarea'); if (!ta) return;
for (i=0;i<ta.length;i++) {
// only autosize textareas actually used to edit tiddler fields
if (ta[i].getAttribute("edit")==undefined) continue;
ta[i].button=src;
if (!ta[i].maxed)
config.commands.autosizeEditor.on(ta[i]);
else
config.commands.autosizeEditor.off(ta[i],true);
}
return false;
},
on: function(e) {
if (e.maxed) return; // already autosizing!
if (e.savedheight==undefined)
e.savedheight=e.style.height;
if (e.savedkeyup==undefined) {
e.savedkeyup=e.onkeyup;
e.onkeyup=function(ev) {
if (!ev) var ev=window.event; var e=resolveTarget(ev);
e.style.height=e.scrollHeight+'px';
if (e.savedkeyup) e.savedkeyup();
}
}
// IE reports error: "not implemented" for onkeypress
if (!config.browser.isIE && e.savedkeypress==undefined) {
e.savedkeypress=e.onkeypress;
e.onkeypress=function(ev) {
if (!ev) var ev=window.event; var e=resolveTarget(ev);
if (ev.keyCode==33) { // PGUP
if (window.scrollByPages) window.scrollByPages(-1);
return false;
}
if (ev.keyCode==34) { // PGDN
if (window.scrollByPages) window.scrollByPages(1);
return false;
}
if (e.savedkeypress) e.savedkeypress();
}
}
e.style.height=e.scrollHeight+'px';
e.button.innerHTML=config.commands.autosizeEditor.text_alt;
e.maxed=true;
},
off: function(e,resetHeight) {
if (resetHeight) e.style.height=e.savedheight;
e.onkeyup=e.savedkeyup;
// IE reports error: "not implemented" for onkeypress
if (!config.browser.isIE) e.onkeypress=e.savedkeypress;
e.button.innerHTML=config.commands.autosizeEditor.text;
e.maxed=false;
}
};
//}}}
// // grab-and-stretch handle
//{{{
config.macros.resizeEditor = { // add stretch bar to editor textarea
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var ta=here.getElementsByTagName('textarea');
if (ta) for (i=0;i<ta.length;i++) {
// only resize tiddler editor textareas
if (ta[i].getAttribute("edit")==undefined) continue;
new window.TextAreaResizer(ta[i]);
}
}
}
config.macros.resizeTiddler = { // add stretch bar to tiddler viewer element
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var elems=here.getElementsByTagName('div');
if (elems) for (i=0;i<elems.length;i++) if (hasClass(elems[i],'viewer')) break;
if (i<elems.length) new window.TextAreaResizer(elems[i]);
}
}
config.macros.resizeFrame = { // add stretch bar to iframes
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var fr=here.getElementsByTagName('iframe');
if (fr) for (i=0;i<fr.length;i++) new window.TextAreaResizer(fr[i]);
}
}
// TextAreaResizer script by Jason Johnston (jj@lojjic.net)
// Created August 2003. Use freely, but give me credit.
// adds a handle below textareas that the user can drag with the mouse to resize the textarea.
// MODIFIED by ELS for cross-browser (IE) compatibility, including:
// fixups and adjustments to CSS styles,
// use 'old style' assignment of mouse event handlers instead of using addEventListener(),
// use window.event if event param is null,
// use offsetHeight instead of getComputedStyle()
// use explicit window.* global scope declaration for functions called from event handlers
window.TextAreaResizer = function(elt) {
this.element = elt;
this.create();
}
window.TextAreaResizer.prototype = {
create : function() {
var elt = this.element;
var thisRef = this;
var h = this.handle = document.createElement("div");
h.style.height = "3px"; // was 4px... looked too fat!
h.style.overflow = "hidden"; // ELS: force IE to trim height to < 1em
h.style.width="auto";
h.style.backgroundColor = "#999"; // ELS: standard mid-tone (dark) gray
h.style.cursor = "s-resize";
h.title = "Drag to resize text box";
h.onmousedown=function(evt){thisRef.dragStart(evt)};
elt.parentNode.insertBefore(h, elt.nextSibling);
},
dragStart : function(evt) {
if (!evt) var evt=window.event;
this.dragStop(evt); // ELS: stop any current drag processing first
var thisRef = this;
this.dragStartY = evt.clientY;
this.dragStartH = this.element.offsetHeight;
document.savedmousemove=document.onmousemove;
document.onmousemove=this.dragMoveHdlr=function(evt){thisRef.dragMove(evt)};
document.savedmouseup=document.onmouseup;
document.onmouseup=this.dragStopHdlr=function(evt){thisRef.dragStop(evt)};
},
dragMove : function(evt) {
if (!evt) var evt=window.event;
// ELS: make sure height is at least 10px
var h=this.dragStartH+evt.clientY-this.dragStartY;
if (h<10) h=10; this.element.style.height=h+"px";
// ELS: match handle to textarea width (which may have changed due to document scrollbars)
this.handle.style.width=(this.element.offsetWidth-4)+"px"; // 4-pixel fudge factor for textarea border edge
// ELS: when manually resizing, disable autoresizing (without restoring saved height)
if (this.element.maxed!=undefined && this.element.maxed)
config.commands.autosizeEditor.off(this.element,false);
},
dragStop : function(evt) {
if (!evt) var evt=window.event;
document.onmousemove=(document.savedmousemove!=undefined)?document.savedmousemove:null;
document.onmousemove=(document.savedmouseup!=undefined)?document.savedmouseup:null;
},
destroy : function() {
var elt = this.element;
elt.parentNode.removeChild(this.handle);
elt.style.height = "";
}
};
//}}}
<<tiddler HideTiddlerTags>>/%
Description: Things I've Learned... (notes and guidelines for successful living)
%/@@display:block;width:80%;margin:0 auto;{{center medium italic{
{{big{Things I've Learned...}}}
(notes and guidelines for successful living)
Eric L Shulman ~ December 11, 2000
explore and express that which comes from
your fundamental ''Nature'' and ''Essence''
be genuine and open to the ''Circumstances''
and the ''Possibilities'' of each moment
act to create ''Joy'' and ''Beauty'' in the world,
and ''Balance'' and ''Harmony'' in your life
embrace all ''Experiences'', positive or negative,
as ''Opportunities'' to learn and grow
honor and respect the ''Differences'' and
''Perspectives'' of everyone you meet
share your ''Hopes'', ''Dreams'', and ''Visions''
with those around you
give thanks for all ''Good Things''
that come your way
be humble in the face of the
''Vast and Infinite Universe''
}}}@@
<<tiddler HideTiddlerTags>>/%
Description: This Crazy Language
%/@@display:block;width:80%;margin:0 auto;{{medium{
{{center{
{{big{This Crazy Language}}}
(author unknown)}}}
Let's face it -- English is a crazy language. There is no egg in eggplant nor ham in hamburger; neither apple nor pine in pineapple. English muffins weren't invented in England or French fries in France. Sweetmeats are candies while sweetbreads, which aren't sweet, are meat.
We take English for granted. But if we explore its paradoxes, we find that quicksand can work slowly, boxing rings are square and a guinea pig is neither from Guinea nor is it a pig.
And why is it that writers write but fingers don't fing, grocers don't groce and hammers don't ham? If the plural of tooth is teeth, why isn't the plural of booth beeth? One goose, 2 geese. So one moose, 2 meese? One index, 2 indices?
Doesn't it seem crazy that you can make amends but not one amend, that you comb thru annals of history but not a single annal? If you have a bunch of odds and ends and get rid of all but one of them, what do you call it?
If teachers taught, why didn't preacher praught? If a vegetarian eats vegetables, what does a humanitarian eat? If you wrote a letter, perhaps you bote your tongue?
Sometimes I think all the English speakers should be committed to an asylum for the verbally insane. In what language do people recite at a play and play at a recital? Ship by truck and send cargo by ship? Have noses that run and feet that smell?
How can a slim chance and a fat chance be the same, while a wise man and wise guy are opposites? How can overlook and oversee be opposites, while quite a lot and quite a few are alike? How can the weather be hot as hell one day and cold as hell another?
Have you noticed that we talk about certain things only when they are absent? Have you ever seen a horseful carriage or a strapful gown? Met a sung hero or experienced requited love? Have you ever run into someone who was combobulated, gruntled, ruly or peccable? And where are all those people who ARE spring chickens or who would ACTUALLY hurt a fly?
You have to marvel at the unique lunacy of a language in which your house can burn up as it burns down, in which you fill in a form by filling it out and in which an alarm clock goes off by going on.
English was invented by people, not computers, and it reflects the creativity of the human race (which, of course, isn't a race at all). That is why, when the stars are out, they are visible, but when the lights are out, they are invisible. And why, when I wind up my watch, I start it, but when I wind up this essay, I end it.
}}}@@
<<tiddler HideTiddlerTags>>/%
Description: Three Blind Mice - an excerpt from "Picnic, Lightning" by Billy Collins
%/@@display:block;width:80%;margin:0 auto;{{center medium italic{
{{big{an excerpt from
"Picnic, Lightning" by Billy Collins}}}
I CHOP SOME PARSLEY WHILE LISTENING TO ART BLAKEY'S VERSION OF "THREE BLIND MICE"
And I start wondering how they came to be blind.
If it was congenital, they could be brothers and sisters, and I think of the poor mother brooding over her sightless young triplets.
Or was it a common accident, all three caught in a searing explosion, a firework perhaps? If not, if each came to his or her blindness separately, how did they ever manage to find one another? Would it not be difficult for a blind mouse to locate even one fellow mouse with vision let alone two other blind ones?
And how, in their tiny darkness, could they possibly have run after a farmer's wife or anyone else's wife for that matter?
Not to mention why.
Just so she could cut off their tails with a carving knife, is the cynic's answer, but the thought of them without eyes and now without tails to trail through the moist grass or slip around the corner of a baseboard has the cynic who always lounges within me up off his couch and at the window trying to hide the rising softness that he feels.
By now I am on to dicing an onion which might account for the wet stinging in my own eyes, though Freddie Hubbard's mournful trumpet on "Blue Moon," which happens to be the next cut, cannot be said to be making matters any better.
}}}@@
{{fine{
>Note: http://www.rhymes.org.uk/three_blind_mice.htm
>The origin of the words to the Three blind mice rhyme are based in English history. The 'farmer's wife' refers to the daughter of King Henry VIII, Queen Mary I. Mary was a staunch Catholic and her violent persecution of Protestants led to the nickname of 'Bloody Mary'. The reference to 'farmer's wife' in Three blind mice refers to the massive estates which she, and her husband King Philip of Spain, possessed. The 'three blind mice' were three noblemen who adhered to the Protestant faith who were convicted of plotting against the Queen - she did not have them dismembered and blinded as inferred in Three blind mice - but she did have them burnt at the stake!
<<tiddler HideTiddlerTags>><<tiddler HideTiddlerBackground>>{{transparent smallform{<<tiddlerTweaker>>}}}
/***
|Name|TiddlerTweakerPlugin|
|Source|http://www.TiddlyTools.com/#TiddlerTweakerPlugin|
|Version|2.3.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||
|Overrides||
|Description|select multiple tiddlers and modify author, created, modified and/or tag values|
~TiddlerTweaker is a tool for TiddlyWiki authors. It allows you to select multiple tiddlers from a listbox, either by direct interaction or automatically matching specific criteria. You can then modify the creator, author, created, modified and/or tag values of those tiddlers using a compact set of form fields. The values you enter into the fields simultantously overwrite the existing values in all tiddlers you have selected.
!!!!!Usage
<<<
{{{<<tiddlerTweaker>>}}}
{{smallform{<<tiddlerTweaker>>}}}
By default, any tags you enter into the TiddlerTweaker will //replace// the existing tags in all the tiddlers you have selected. However, you can also use TiddlerTweaker to quickly filter specified tags from the selected tiddlers, while leaving any other tags assigned to those tiddlers unchanged:
>Any tag preceded by a "+" (plus) or "-" (minus), will be added or removed from the existing tags //instead of replacing the entire tag definition// of each tiddler (e.g., enter "-excludeLists" to remove that tag from all selected tiddlers. When using this syntax, care should be taken to ensure that //every// tag is preceded by "+" or "-", to avoid inadvertently overwriting any other existing tags on the selected tiddlers. (note: the "+" or "-" prefix on each tag value is NOT part of the tag value, and is only used by TiddlerTweaker to control how that tag value is processed)
Important Notes:
* Inasmuch as TiddlerTweaker is a 'power user' tool that can perform 'batch' functions (operating on many tiddlers at once), you should always have a recent backup of your document (or "save changes" just *before* tweaking the tiddlers), just in case you "shoot yourself in the foot".
* By design, TiddlerTweaker does NOT update the 'modified' date of tiddlers simply by making changes to the tiddler's values. A tiddler's dates are ONLY updated when the corresponding 'created' and/or 'modified' checkboxes are selected and you enter new values for those dates. As a general rule, after using TiddlerTweaker, always ''//remember to save your document//'' when you are done, even though the tiddler timeline tab may not show any recently modified tiddlers.
* Because you may be changing the values on many tiddlers simultaneously, selecting and updating all tiddlers in a document operation may take a while and your browser might warn about an "unresponsive script"... you should give it a whole bunch of time to 'continue'... it should complete the processing... eventually.
<<<
!!!!!Revisions
<<<
2009.01.22 [2.3.0] added support for text pattern find/replace
2008.10.27 [2.2.3] in setTiddlers(), fixed Safari bug by replacing static Array.concat(...) with new Array().concat(...)
2008.09.07 [2.2.2] added removeCookie() function for compatibility with [[CookieManagerPlugin]]
2008.05.12 [2.2.1] replace built-in backstage "tweak" task with tiddler tweaker control panel (moved from BackstageTweaks)
2008.01.13 [2.2.0] added "auto-selection" links: all, changed, tags, title, text
2007.12.26 [2.1.0] added support for managing 'creator' custom field (see [[CoreTweaks]])
2007.11.01 [2.0.3] added config.options.txtTweakerSortBy for cookie-based persistence of list display order preference setting.
2007.09.28 [2.0.2] in settiddlers() and deltiddlers(), added suspend/resume notification handling (improves performance when operating on multiple tiddlers)
2007.08.03 [2.0.1] added shadow definition for [[TiddlerTweaker]] tiddler for use as parameter references with {{{<<tiddler>>, <<slider>> or <<tabs>>}}} macros.
2007.08.03 [2.0.0] converted from inline script
2006.01.01 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TiddlerTweakerPlugin= {major: 2, minor: 3, revision: 0, date: new Date(2009,1,22)};
// shadow tiddler
config.shadowTiddlers.TiddlerTweaker="<<tiddlerTweaker>>";
/// backstage task
if (config.tasks) { // for TW2.2b3 or above
config.tasks.tweak.tooltip="review/modify tiddler internals: dates, authors, tags, etc.";
config.tasks.tweak.content="{{smallform small groupbox{<<tiddlerTweaker>>}}}";
}
if (config.options.txtTweakerSortBy==undefined) config.options.txtTweakerSortBy="modified";
// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
window.removeCookie=function(name) {
document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
}
}
config.macros.tiddlerTweaker = {
html: '<form style="display:inline"><!--\
--><table style="padding:0;margin:0;border:0;width:100%"><tr valign="top" style="padding:0;margin:0;border:0"><!--\
--><td style="text-align:center;white-space:nowrap;width:99%;padding:0;margin:0;border:0"><!--\
--><font size=-2><div style="text-align:left;"><span style="float:right"><!--\
--> <a href="javascript:;" \
title="select all tiddlers"\
onclick="\
var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
for (var t=0; t<f.list.options.length; t++)\
if (f.list.options[t].value.length) f.list.options[t].selected=true;\
config.macros.tiddlerTweaker.selecttiddlers(f.list);\
return false">all</a><!--\
--> <a href="javascript:;" \
title="select tiddlers that are new/changed since the last file save"\
onclick="\
var lastmod=new Date(document.lastModified);\
var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
for (var t=0; t<f.list.options.length; t++) {\
var tid=store.getTiddler(f.list.options[t].value);\
f.list.options[t].selected=tid&&tid.modified>lastmod;\
}\
config.macros.tiddlerTweaker.selecttiddlers(f.list);\
return false">changed</a><!--\
--> <a href="javascript:;" \
title="select tiddlers with at least one matching tag"\
onclick="\
var t=prompt(\'Enter space-separated tags (match ONE)\');\
if (!t||!t.length) return false;\
var tags=t.readBracketedList();\
var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
for (var t=0; t<f.list.options.length; t++) {\
f.list.options[t].selected=false;\
var tid=store.getTiddler(f.list.options[t].value);\
if (tid&&tid.tags.containsAny(tags)) f.list.options[t].selected=true;\
}\
config.macros.tiddlerTweaker.selecttiddlers(f.list);\
return false">tags</a><!--\
--> <a href="javascript:;" \
title="select tiddlers whose titles include matching text"\
onclick="\
var txt=prompt(\'Enter a title (or portion of a title) to match\');\
if (!txt||!txt.length) return false;\
var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
for (var t=0; t<f.list.options.length; t++) {\
f.list.options[t].selected=f.list.options[t].value.indexOf(txt)!=-1;\
}\
config.macros.tiddlerTweaker.selecttiddlers(f.list);\
return false">titles</a><!--\
--> <a href="javascript:;" \
title="select tiddlers containing matching text"\
onclick="\
var txt=prompt(\'Enter tiddler text (content) to match\');\
if (!txt||!txt.length) return false;\
var f=this; while (f&&f.nodeName.toLowerCase()!=\'form\')f=f.parentNode;\
for (var t=0; t<f.list.options.length; t++) {\
var tt=store.getTiddlerText(f.list.options[t].value,\'\');\
f.list.options[t].selected=(tt.indexOf(txt)!=-1);\
}\
config.macros.tiddlerTweaker.selecttiddlers(f.list);\
return false">text</a> <!--\
--></span><span>select tiddlers</span><!--\
--></div><!--\
--></font><select multiple name=list size="11" style="width:99.99%" \
title="use click, shift-click and/or ctrl-click to select multiple tiddler titles" \
onclick="config.macros.tiddlerTweaker.selecttiddlers(this)" \
onchange="config.macros.tiddlerTweaker.setfields(this)"><!--\
--></select><br><!--\
-->show<input type=text size=1 value="11" \
onchange="this.form.list.size=this.value; this.form.list.multiple=(this.value>1);"><!--\
-->by<!--\
--><select name=sortby size=1 \
onchange="config.macros.tiddlerTweaker.init(this.form,this.value)"><!--\
--><option value="title">title</option><!--\
--><option value="size">size</option><!--\
--><option value="modified">modified</option><!--\
--><option value="created">created</option><!--\
--></select><!--\
--><input type="button" value="refresh" \
onclick="config.macros.tiddlerTweaker.init(this.form,this.form.sortby.value)"<!--\
--> <input type="button" name="stats" disabled value="totals..." \
onclick="config.macros.tiddlerTweaker.stats(this)"><!--\
--></td><td style="white-space:nowrap;padding:0;margin:0;border:0;width:1%"><!--\
--><div style="text-align:left"><font size=-2> modify values</font></div><!--\
--><table border=0 style="width:100%;padding:0;margin:0;border:0;"><tr style="padding:0;border:0;"><!--\
--><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=checkbox name=settitle unchecked \
title="allow changes to tiddler title (rename tiddler)" \
onclick="this.form.title.disabled=!this.checked">title<!--\
--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=text name=title size=35 style="width:98%" disabled><!--\
--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=checkbox name=setcreator unchecked \
title="allow changes to tiddler creator" \
onclick="this.form.creator.disabled=!this.checked">created by<!--\
--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=text name=creator size=35 style="width:98%" disabled><!--\
--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=checkbox name=setwho unchecked \
title="allow changes to tiddler author" \
onclick="this.form.who.disabled=!this.checked">modified by<!--\
--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=text name=who size=35 style="width:98%" disabled><!--\
--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=checkbox name=setcdate unchecked \
title="allow changes to created date" \
onclick="var f=this.form; f.cm.disabled=f.cd.disabled=f.cy.disabled=f.ch.disabled=f.cn.disabled=!this.checked"><!--\
-->created on<!--\
--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=text name=cm size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--> / <input type=text name=cd size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--> / <input type=text name=cy size=4 style="width:3em;padding:0;text-align:center" disabled><!--\
--> at <input type=text name=ch size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--> : <input type=text name=cn size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=checkbox name=setmdate unchecked \
title="allow changes to modified date" \
onclick="var f=this.form; f.mm.disabled=f.md.disabled=f.my.disabled=f.mh.disabled=f.mn.disabled=!this.checked"><!--\
-->modified on<!--\
--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=text name=mm size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--> / <input type=text name=md size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--> / <input type=text name=my size=4 style="width:3em;padding:0;text-align:center" disabled><!--\
--> at <input type=text name=mh size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--> : <input type=text name=mn size=2 style="width:2em;padding:0;text-align:center" disabled><!--\
--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=checkbox name=replacetext unchecked\
title="find/replace matching text" \
onclick="this.form.pattern.disabled=this.form.replacement.disabled=!this.checked">replace text<!--\
--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=text name=pattern size=15 value="" style="width:40%" disabled \
title="enter TEXT PATTERN (regular expression)"> with <!--\
--><input type=text name=replacement size=15 value="" style="width:40%" disabled \
title="enter REPLACEMENT TEXT"><!--\
--></td></tr><tr style="padding:0;border:0;"><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=checkbox name=settags checked \
title="allow changes to tiddler tags" \
onclick="this.form.tags.disabled=!this.checked">tags<!--\
--></td><td style="padding:1px;border:0;white-space:nowrap"><!--\
--><input type=text name=tags size=35 value="" style="width:98%" \
title="enter new tags or use \'+tag\' and \'-tag\' to add/remove tags from existing tags"><!--\
--></td></tr></table><!--\
--><div style="text-align:center"><!--\
--><nobr><input type=button name=display disabled style="width:32%" value="display tiddlers" \
onclick="config.macros.tiddlerTweaker.displaytiddlers(this)"><!--\
--> <input type=button name=del disabled style="width:32%" value="delete tiddlers" \
onclick="config.macros.tiddlerTweaker.deltiddlers(this)"><!--\
--> <input type=button name=set disabled style="width:32%" value="update tiddlers" \
onclick="config.macros.tiddlerTweaker.settiddlers(this)"></nobr><!--\
--></div><!--\
--></td></tr></table><!--\
--></form><span style="display:none"><!--content replaced by tiddler "stats"--></span>\
',
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var span=createTiddlyElement(place,"span");
span.innerHTML=this.html;
this.init(span.firstChild,config.options.txtTweakerSortBy);
},
init: function(f,sortby) { // initialize form controls
if (!f) return; // form might not be rendered yet...
while (f.list.options[0]) f.list.options[0]=null; // empty current list content
var tids=store.getTiddlers(sortby);
if (sortby=="size") // descending order (largest tiddlers listed first)
tids.sort(function(a,b) {return a.text.length > b.text.length ? -1 : (a.text.length == b.text.length ? 0 : +1);});
for (i=0; i<tids.length; i++) {
var label=tids[i].title; var value=tids[i].title;
if (sortby=="modified" || sortby=="created") {
label=tids[tids.length-i-1][sortby].formatString("YY.0MM.0DD 0hh:0mm ")+tids[tids.length-i-1].title;
value=tids[tids.length-i-1].title;
}
if (sortby=="size") label="["+tids[i].text.length+"] "+label;
f.list.options[f.list.length]=new Option(label,value,false,false);
}
f.title.value=f.who.value=f.creator.value=f.tags.value="";
f.cm.value=f.cd.value=f.cy.value=f.ch.value=f.cn.value="";
f.mm.value=f.md.value=f.my.value=f.mh.value=f.mn.value="";
f.stats.disabled=f.set.disabled=f.del.disabled=f.display.disabled=true;
f.settitle.disabled=false;
config.options.txtTweakerSortBy=sortby; // remember current setting
f.sortby.value=sortby; // sync droplist selection with current setting
if (sortby!="modified") // non-default preference... save cookie
saveOptionCookie("txtTweakerSortBy");
else removeCookie("txtTweakerSortBy"); // default preference... clear cookie
},
selecttiddlers: function(here) { // enable/disable tweaker fields based on number of items selected
// count how many tiddlers are selected
var f=here.form; var list=f.list;
var c=0; for (i=0;i<list.length;i++) if (list.options[i].selected) c++;
if (c>1) f.title.disabled=true;
if (c>1) f.settitle.checked=false;
f.set.disabled=(c==0);
f.del.disabled=(c==0);
f.display.disabled=(c==0);
f.settitle.disabled=(c>1);
f.stats.disabled=(c==0);
var msg=(c==0)?'select tiddlers':(c+' tiddler'+(c!=1?'s':'')+' selected');
here.previousSibling.firstChild.firstChild.nextSibling.innerHTML=msg;
if (c) clearMessage(); else displayMessage("no tiddlers selected");
},
setfields: function(here) { // set tweaker edit fields from first selected tiddler
var f=here.form;
if (!here.value.length) {
f.title.value=f.who.value=f.creator.value=f.tags.value="";
f.cm.value=f.cd.value=f.cy.value=f.ch.value=f.cn.value="";
f.mm.value=f.md.value=f.my.value=f.mh.value=f.mn.value="";
return;
}
var tid=store.getTiddler(here.value); if (!tid) return;
f.title.value=tid.title;
f.who.value=tid.modifier;
f.creator.value=tid.fields['creator']||''; // custom field - might not exist
f.tags.value=tid.tags.join(' ');
var c=tid.created; var m=tid.modified;
f.cm.value=c.getMonth()+1;
f.cd.value=c.getDate();
f.cy.value=c.getFullYear();
f.ch.value=c.getHours();
f.cn.value=c.getMinutes();
f.mm.value=m.getMonth()+1;
f.md.value=m.getDate();
f.my.value=m.getFullYear();
f.mh.value=m.getHours();
f.mn.value=m.getMinutes();
},
settiddlers: function(here) {
var f=here.form; var list=f.list;
var tids=[];
for (i=0;i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
if (!tids.length) { alert("please select at least one tiddler"); return; }
var cdate=new Date(f.cy.value,f.cm.value-1,f.cd.value,f.ch.value,f.cn.value);
var mdate=new Date(f.my.value,f.mm.value-1,f.md.value,f.mh.value,f.mn.value);
if (tids.length>1 && !confirm("Are you sure you want to update these tiddlers:\n\n"+tids.join(', '))) return;
store.suspendNotifications();
for (t=0;t<tids.length;t++) {
var tid=store.getTiddler(tids[t]); if (!tid) continue;
var title=!f.settitle.checked?tid.title:f.title.value;
var who=!f.setwho.checked?tid.modifier:f.who.value;
var text=tid.text;
if (f.replacetext.checked) text=text.replace(new RegExp(f.pattern.value,'mg'),f.replacement.value);
var tags=tid.tags;
if (f.settags.checked) {
var intags=f.tags.value.readBracketedList();
var addtags=[]; var deltags=[]; var reptags=[];
for (i=0;i<intags.length;i++) {
if (intags[i].substr(0,1)=='+')
addtags.push(intags[i].substr(1));
else if (intags[i].substr(0,1)=='-')
deltags.push(intags[i].substr(1));
else
reptags.push(intags[i]);
}
if (reptags.length)
tags=reptags;
if (addtags.length)
tags=new Array().concat(tags,addtags);
if (deltags.length)
for (i=0;i<deltags.length;i++)
{ var pos=tags.indexOf(deltags[i]); if (pos!=-1) tags.splice(pos,1); }
}
if (!f.setcdate.checked) cdate=tid.created;
if (!f.setmdate.checked) mdate=tid.modified;
store.saveTiddler(tid.title,title,text,who,mdate,tags,tid.fields);
if (f.setcreator.checked) store.setValue(tid.title,'creator',f.creator.value); // set creator
if (f.setcdate.checked) tid.assign(null,null,null,null,null,cdate); // set create date
}
store.resumeNotifications();
this.init(f,f.sortby.value);
},
displaytiddlers: function(here) {
var f=here.form; var list=f.list;
var tids=[];
for (i=0; i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
if (!tids.length) { alert("please select at least one tiddler"); return; }
story.displayTiddlers(story.findContainingTiddler(f),tids)
},
deltiddlers: function(here) {
var f=here.form; var list=f.list;
var tids=[];
for (i=0;i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
if (!tids.length) { alert("please select at least one tiddler"); return; }
if (!confirm("Are you sure you want to delete these tiddlers:\n\n"+tids.join(', '))) return;
store.suspendNotifications();
for (t=0;t<tids.length;t++) {
var tid=store.getTiddler(tids[t]); if (!tid) continue;
if (tid.tags.contains("systemConfig"))
if (!confirm("'"+tid.title+"' is tagged with 'systemConfig'.\n\nRemoving this tiddler may cause unexpected results. Are you sure?"))
continue;
store.removeTiddler(tid.title);
story.closeTiddler(tid.title);
}
store.resumeNotifications();
this.init(f,f.sortby.value);
},
stats: function(here) {
var f=here.form; var list=f.list; var tids=[]; var out=''; var tot=0;
var target=f.nextSibling;
for (i=0;i<list.length;i++) if (list.options[i].selected) tids.push(list.options[i].value);
if (!tids.length) { alert("please select at least one tiddler"); return; }
for (t=0;t<tids.length;t++) {
var tid=store.getTiddler(tids[t]); if (!tid) continue;
out+='[['+tid.title+']] '+tid.text.length+'\n'; tot+=tid.text.length;
}
var avg=tot/tids.length;
out=tot+' bytes in '+tids.length+' selected tiddlers ('+avg+' bytes/tiddler)\n<<<\n'+out+'<<<\n';
removeChildren(target);
target.innerHTML="<hr><font size=-2><a href='javascript:;' style='float:right' "
+"onclick='this.parentNode.parentNode.style.display=\"none\"'>close</a></font>";
wikify(out,target);
target.style.display="block";
}
};
//}}}
/***
|Name|TiddlyBlogSetupPlugin|
|Source|http://www.TiddlyTools.com/quickstart/tiddlyblog#TiddlyBlogSetupPlugin|
|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|plugin|
|Requires||
|Overrides||
|Description|initialize tiddlyblog internal values|
!!!!!Revisions
<<<
2009.03.26 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TiddlyBlogSetupPlugin= {major: 1, minor: 0, revision: 0, date: new Date(2009,3,26)};
config.shadowTiddlers['SiteUrl']="http://www.TiddlyTools.com/quickstart/tiddlyblog.html";
config.shadowTiddlers['PoweredByTiddlyBlog']="\n"
+"''powered by [[tiddlyblog|"+config.shadowTiddlers['SiteUrl']+"]]''\n"
+"//portable blogging...\n"
+"...anytime, anywhere!//";
//}}}
/%
|Name|ToggleBreadcrumbs|
|Source|http://www.TiddlyTools.com/#ToggleBreadcrumbs|
|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|BreadcrumbsPlugin, InlineJavascriptPlugin|
|Overrides||
|Description|dynamically enable/disable BreadcrumbsPlugin display|
%/<script>
if (config.options.chkShowBreadcrumbs==undefined) config.options.chkShowBreadcrumbs=true;
</script><<option chkShowBreadcrumbs>><script>
var chk=place.lastChild;
chk.coreOnChange=chk.onchange;
chk.onchange=function() {
if (this.coreOnChange) this.coreOnChange.apply(this,arguments);
this.checked=config.options.chkShowBreadcrumbs;
if (config.macros.breadcrumbs) config.macros.breadcrumbs.refresh();
};
</script>
/%
|Name|ToggleFullScreen|
|Source|http://www.TiddlyTools.com/#ToggleFullScreen|
|Version|1.1.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|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|show/hide main menu, sidebar and page header|
Usage:
<<tiddler ToggleFullScreen with: label altlabel>>
- displays 'onclick' command link that toggles full screen display mode
or
<<tiddler ToggleFullScreen##ON>>
- immediately sets full screen mode
or
<<tiddler ToggleFullScreen##OFF>>
- immediately resets full screen mode
!ON
<script> if (!config.options.chkFullScreen) window.toggleFullScreen(); </script>
!end ON
!OFF
<script> if (config.options.chkFullScreen) window.toggleFullScreen(); </script>
!end OFF
%/<script>
window.toggleFullScreen=function(here) {
config.options.chkFullScreen=!config.options.chkFullScreen;
var showmm=!config.options.chkFullScreen && config.options.chkShowLeftSidebar!==false;
var showsb=!config.options.chkFullScreen && config.options.chkShowRightSidebar!==false;
var showcrumbs=!config.options.chkFullScreen && config.options.chkShowBreadcrumbs!==false
&& config.macros.breadcrumbs && config.macros.breadcrumbs.crumbs.length;
var cw=document.getElementById('contentWrapper');
var da=document.getElementById('displayArea');
var mm=document.getElementById('mainMenu');
var sb=document.getElementById('sidebar');
var sm=document.getElementById('storyMenu');
var bc=document.getElementById('breadCrumbs');
var sn=document.getElementById('siteNav');
if (cw){
for (var i=0; i<cw.childNodes.length; i++)
if (hasClass(cw.childNodes[i],'header')) { var h=cw.childNodes[i]; break; }
if (h) h.style.display=!config.options.chkFullScreen?'block':'none';
}
if (mm) {
mm.style.display=showmm?'block':'none';
da.style.marginLeft=showmm?(config.options.txtDisplayAreaLeftMargin||''):'1em';
}
if (sb) {
sb.style.display=showsb?'block':'none';
da.style.marginRight=showsb?(config.options.txtDisplayAreaRightMargin||''):'1em';
}
if (sm)
sm.style.display=!config.options.chkFullScreen ?'block':'none';
if (bc)
bc.style.display=showcrumbs?'block':'none';
if (sn)
sn.style.display=!config.options.chkFullScreen?'block':'none';
var label=('$'+'1'=='$1')?'fullscreen':'$1';
var altlabel='$2'; if ('$'+'2'=='$2') altlabel=label;
if (typeof(here)!='undefined' && here!=window.place)
here.innerHTML=!config.options.chkFullScreen?label:altlabel;
var b=document.getElementById('restoreFromFullscreenButton');
if (b) removeNode(b);
else {
var b=createTiddlyElement(null,'span','restoreFromFullscreenButton','selected');
b.innerHTML='◊';
b.title='RESTORE: redisplay page header, menu and sidebar';
b.onclick=window.toggleFullScreen;
var s=b.style;
s.position='fixed'; s.top='.3em'; s.right='.3em'; s.zIndex='10001';
s.border='2px outset ButtonFace';
s.padding='0px 3px';
s.cursor='pointer';
s.fontSize='8pt';
s.backgroundColor='ButtonFace';
if (config.browser.isGecko) {
s.color='ButtonText !important';
s.MozAppearance='button';
}
document.body.insertBefore(b,null);
}
return false;
};
</script>/%
%/<script label="$1" title="FULLSCREEN: toggle display of mainmenu, sidebar, and page header">
window.toggleFullScreen(place);
return false;
</script><script>
place.lastChild.innerHTML=('$'+'1'=='$1')?'fullscreen':'$1';
</script>
/%
|Name|ToggleLeftSidebar|
|Source|http://www.TiddlyTools.com/#ToggleLeftSidebar|
|Version|2.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|show/hide left sidebar (MainMenu)|
Usage: <<tiddler ToggleLeftSidebar with: "label">>
Config settings:
config.options.chkShowLeftSidebar (true)
config.options.txtToggleLeftSideBarLabelShow (►)
config.options.txtToggleLeftSideBarLabelHide (◄)
%/<script label="$1" title="show/hide MainMenu content">
var co=config.options;
if (co.chkShowLeftSidebar=='undefined') co.chkShowLeftSidebar=true;
co.chkShowLeftSidebar=!co.chkShowLeftSidebar;
var mm=document.getElementById('mainMenu'); if (!mm) return;
mm.style.display=co.chkShowLeftSidebar?'block':'none';
document.getElementById('displayArea').style.marginLeft=co.chkShowLeftSidebar?'':'1em';
saveOptionCookie('chkShowLeftSidebar');
var labelShow=co.txtToggleLeftSideBarLabelShow||'►';
var labelHide=co.txtToggleLeftSideBarLabelHide||'◄';
if (typeof(place)!='undefined' && '$1'=='$'+'1') {
place.innerHTML=co.chkShowLeftSidebar?labelHide:labelShow;
place.title=(co.chkShowLeftSidebar?'hide':'show')+' left sidebar';
}
var sm=document.getElementById('storyMenu'); if (sm) config.refreshers.content(sm);
</script><script>
var co=config.options;
if (co.chkShowLeftSidebar=='undefined') co.chkShowLeftSidebar=true;
var mm=document.getElementById('mainMenu'); if (!mm) return;
mm.style.display=co.chkShowLeftSidebar?'block':'none';
document.getElementById('displayArea').style.marginLeft=co.chkShowLeftSidebar?'':'1em';
if ('$1'=='$'+'1') {
var labelShow=co.txtToggleLeftSideBarLabelShow||'►';
var labelHide=co.txtToggleLeftSideBarLabelHide||'◄';
place.lastChild.innerHTML=co.chkShowLeftSidebar?labelHide:labelShow;
place.lastChild.title=(co.chkShowLeftSidebar?'hide':'show')+' left sidebar';
}
</script>
/%
|Name|ToggleRightSidebar|
|Source|http://www.TiddlyTools.com/#ToggleRightSidebar|
|Version|2.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|show/hide right sidebar (MainMenu)|
Usage: <<tiddler ToggleRightSidebar with: "label">>
Config settings:
config.options.chkShowRightSidebar (true)
config.options.txtToggleRightSideBarLabelShow (◄)
config.options.txtToggleRightSideBarLabelHide (►)
%/<script label="$1" title="show/hide right sidebar content">
var co=config.options;
if (co.chkShowRightSidebar=='undefined') co.chkShowRightSidebar=true;
co.chkShowRightSidebar=!co.chkShowRightSidebar;
var sb=document.getElementById('sidebar'); if (!sb) return;
sb.style.display=co.chkShowRightSidebar?'block':'none';
document.getElementById('displayArea').style.marginRight=co.chkShowRightSidebar?'':'1em';
saveOptionCookie('chkShowRightSidebar');
var labelShow=co.txtToggleRightSideBarLabelShow||'◄';
var labelHide=co.txtToggleRightSideBarLabelHide||'►';
if (typeof(place)!='undefined' && '$1'=='$'+'1') {
place.innerHTML=co.chkShowRightSidebar?labelHide:labelShow;
place.title=(co.chkShowRightSidebar?'hide':'show')+' right sidebar';
}
var sm=document.getElementById('storyMenu'); if (sm) config.refreshers.content(sm);
</script><script>
var co=config.options;
if (co.chkShowRightSidebar=='undefined') co.chkShowRightSidebar=true;
var sb=document.getElementById('sidebar'); if (!sb) return;
sb.style.display=co.chkShowRightSidebar?'block':'none';
document.getElementById('displayArea').style.marginRight=co.chkShowRightSidebar?'':'1em';
if ('$1'=='$'+'1') {
var labelShow=co.txtToggleRightSideBarLabelShow||'◄';
var labelHide=co.txtToggleRightSideBarLabelHide||'►';
place.lastChild.innerHTML=co.chkShowRightSidebar?labelHide:labelShow;
place.lastChild.title=(co.chkShowRightSidebar?'hide':'show')+' right sidebar';
}
</script>
|~ViewToolbar|collapseTiddler collapseOthers RefreshCommand snapshotPrint closeTiddler closeOthers +editTiddler > < * fields permalink references jump|
|~CollapsedToolbar|+expandTiddler collapseOthers RefreshCommand snapshotPrint closeTiddler closeOthers editTiddler > < * fields permalink references jump|
|~EditToolbar|+saveTiddler -cancelTiddler copyTiddler deleteTiddler autosizeEditor|
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'lumpymilk';
// ADDITIONAL SETTINGS FOR DEFAULT USE OF <<upload>> WITHOUT PARAMS
config.options.txtUploadStoreUrl='http://lumpymilk.tiddlyspot.com/store.cgi';
config.options.txtUploadFilename='index.html';
config.options.txtUploadBackupDir='.';
config.options.txtUploadDir='.';
config.options.txtUploadUserName='lumpymilk';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n")
});
//}}}
/%
|Name|TwitterTabs|
|Source|http://www.TiddlyTools.com/#TwitterTabs|
|Version|1.0.1|
|Author|Eric Shulman|
|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|display a tabset with current Twitter feeds|
%/<<tiddler HideTiddlerBackground>><<tiddler HideTiddlerTags>>/%
- - - - - TAB DEFINITIONS - - - - -
%/<<tabs txtTwitterTabs
'tiddlytools' 'show tweets from @tiddlytools' [[TwitterTabs##tiddlytools]]
'jermolene' 'show tweets from @jermolene' [[TwitterTabs##jermolene]]
'find...' 'find tweets containing...' [[TwitterTabs##search]]
'from...' 'show tweets from...' [[TwitterTabs##user]]
>>/%
!tiddlytools
<<tiddler [[TwitterTabs##showUserResults]] with: tiddlytools>>
!jermolene
<<tiddler [[TwitterTabs##showUserResults]] with: jermolene>>
!search
<<tiddler [[TwitterTabs##showSearchForm]] with: {{config.options.txtTweetSearch||'TiddlyWiki'}}>>
!user
<<tiddler [[TwitterTabs##showUserForm]] with: {{config.options.txtTweetUser||'TiddlyWiki'}}>>
!end
- - - - - TAB CONTENT FORMATTING - - - - -
!showSearchForm
{{small smallform{
search for tweets containing: <<option {{config.options.txtTweetSearch='$1';'txtTweetSearch'}}>><html>
<hide linebreaks><input type='button' value='search' onclick="
var target=this.parentNode.parentNode.parentNode;
var out='\<\<tiddler [[TwitterTabs##showSearchForm]] with: {{config.options.txtTweetSearch}}\>\>';
removeChildren(target); wikify(out,target);
"></html>@@display:block;white-space:normal;<<tiddler [[TwitterTabs##showSearchResults]]
with: {{config.options.txtTweetSearch}}>>@@}}}
!end
!showUserForm
{{small smallform{
show tweets from: <<option {{config.options.txtTweetUser='$1';'txtTweetUser'}}>><html>
<hide linebreaks><input type='button' value='search' onclick="
var target=this.parentNode.parentNode.parentNode;
var out='\<\<tiddler [[TwitterTabs##showUserForm]] with: {{config.options.txtTweetUser}}\>\>';
removeChildren(target); wikify(out,target);
"></html>@@display:block;white-space:normal;<<tiddler [[TwitterTabs##showUserResults]]
with: {{config.options.txtTweetUser}}>>@@}}}
!end
!showSearchResults
{{toolbar{<script label="refresh">
var target=place.parentNode.parentNode;
var out='\<\<tiddler [[TwitterTabs##showSearchResults]] with: [[$1]]\>\>';
removeChildren(target); wikify(out,target);
</script>}}}~~__[[Recent tweets about: "$1"|http://search.twitter.com/search?q=$1]]__~~
<hr>@@display:block;height:20em;overflow:auto;<script>
window.twitterPlace=place;
</script><script src="http://search.twitter.com/search.json?q=$1&rpp=25&callback=twitterCallback">
</script>@@@@display:block;text-align:right;^^scroll for more...^^@@
!end
!showUserResults
{{toolbar{<script label="refresh">
var target=place.parentNode.parentNode;
var out='\<\<tiddler [[TwitterTabs##showUserResults]] with: [[$1]]\>\>';
removeChildren(target); wikify(out,target);
</script>}}}~~__[[Recent tweets from $1|http://twitter.com/$1]]__~~
<hr>@@display:block;height:20em;overflow:auto;<script>
window.twitterPlace=place;
</script><script src="http://twitter.com/statuses/user_timeline/$1.json?callback=twitterCallback">
</script>@@@@display:block;text-align:right;^^scroll for more...^^@@
!end
- - - - - TWEET ITEM FORMAT - - - - -
| where: %0=image, %1=name, %2=text, %3=timestamp
| note: "(48px+,48px+)" syntax requires [[ImageSizePlugin]]
!itemFormat
{{small{
[<img(48px+,48px+)[%0]][[%1|http://twitter.com/%1]]: %2
{{fine{
%3}}} {{clear{
}}}
}}}
!end
- - - - - CALLBACK RENDERING FUNCTION - - - - -
%/<script>
window.twitterCallback=function(data){ // data object returned from twitter.com
var fmt=store.getTiddlerText('TwitterTabs##itemFormat');
if (data.results) data=data.results; // for SEARCH results
removeChildren(window.twitterPlace);
for (var i=0; i<data.length; i++) { var item=data[i];
var img=item.user? item.user.profile_image_url : item.profile_image_url;
var who=item.user? item.user.screen_name : item.from_user;
wikify(fmt.format([img,who,item.text,item.created_at]),window.twitterPlace);
}
}
</script>
/***
|Name|UnsavedChangesPlugin|
|Source|http://www.TiddlyTools.com/#UnsavedChangesPlugin|
|Version|3.3.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|TiddlyWiki.prototype.setDirty,store.saveTiddler,store.removeTiddler|
|Description|show droplist of tiddlers that have changed since the last time the document was saved|
Display a list of tiddlers that have been changed since the last time the document was saved. The list includes all new/modified tiddlers as well as those changed with "minor edits" enabled and any tiddlers that you import during the session, regardless of their modification date.
!!!!!Usage
<<<
{{{
<<unsavedChanges panel>> or <<unsavedChanges>>
}}}
{{indent{
the ''panel'' keyword displays a 'control panel' interface containing a droplist of unsaved tiddlers and a 'goto' button, along with a command link to 'save changes'. Depending upon what other plugins are installed, several additional elements will also be displayed: When [[NestedSlidersPlugin]] is installed, the entire control panel is contained within a ''SLIDER''. When [[LoadTiddlersPlugin]] is installed, a ''REVERT'' button is added. When [[SaveAsPlugin]] is installed, a ''SAVE AS'' link is added. When [[UploadPlugin]] is installed, an ''UPLOAD'' (or ''save to web'') link is added. When [[TrashPlugin]] is installed and there are tiddlers tagged with<<tag Trash>>, an ''EMPTY TRASH'' link is added.
}}}
{{{
<<unsavedChanges list separator>>
}}}
{{indent{
the ''list'' keyword displays a simple space-separated list of unsaved tiddlers without any other command links. You can specify an optional ''separator'' value that can be used in place of the default space character. For example, you can specify {{{"<br>"}}} as the separator in order to display each link, one per line.
}}}
{{{
<<unsavedChanges command label tip>>
}}}
{{indent{
the ''command'' keyword displays a single 'command link' that, when clicked, displays a ~TiddlyWiki popup containing the list of unsaved tiddlers, the 'save changes' command and, depending upon what other plugins are installed, additional commands for 'save as', 'upload', and 'empty trash' (similar to the panel display described above).
You can specify optional ''label'' and ''tip'' parameters in the macro to customize the command link text and tooltip. The default label for the command link is: "There %1 %0 unsaved tiddler%2...", where:
* %0 is automatically replaced with the number of unsaved changes
* %1 is either "is" (if changes=1) or "are" (if changes>1)
* %2 is either blank (if changes=1) or "s" (if changes>1)
resulting in the text: //"There is 1 unsaved tiddler...", "There are 2 unsaved tiddlers...", etc.//
}}}
<<<
!!!!!Examples
<<<
^^//note: the following examples will not display any output unless you have already created/modified tiddlers in the current document.//^^
{{{<<unsavedChanges>>}}}
<<unsavedChanges>>
----
{{{<<unsavedChanges command>>}}}
<<unsavedChanges command>>
----
{{{<<unsavedChanges list>>}}}
<<unsavedChanges list>>
----
{{{<<unsavedChanges list "<br>">>}}}
<<unsavedChanges list "<br>">>
<<<
!!!!!Revisions
<<<
2009.03.02 [3.3.3] fix handling for titles that contain HTML special chars (lt,gt,quot,amp)
2008.09.02 [3.3.2] cleanup popup list output generation and added timestamps/sizes to popup display
2008.08.23 [3.3.1] added optional custom 'label' and 'tip' params to 'command' mode and defined default values for mode, label, tip, and separator as object properties for I18N/L10N-readiness.
2008.08.21 [3.3.0] complete re-write of rendering and refresh processing to support multiple instances and automatic self-refresh (no longer depends upon core refresh notifications)
2008.08.21 [3.2.0] added 'command' option for link+popup as alternative to 'control panel' interface
2008.04.22 [3.1.2] use SaveAsPlugin instead of obsolete NewDocumentPlugin to add "save as" link
2007.12.22 [3.1.1] hijack removeTiddler() instead of low-level deleteTiddler() to correct tracking and refresh handling issues. in saveTiddler(), check for 'tiddler rename' (title!=newtitle) and adjust list accordingly.
2007.12.21 [3.1.0] added support for {{{<<unsavedChanges list separator>>}}} usage to unsaved tiddlers as a simple list of links, embedded in tiddler content (e.g., [[MainMenu]])
2007.12.20 [3.0.0] rewrite to track ALL changed tiddlers, including imports and minor edits, regardless of saved modification dates. Also, rewrote display logic to directly refresh macro output instead of triggering a page refresh. The entire process is MUCH more efficient now.
2007.08.02 [2.0.0] converted from inline script
2007.01.01 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.UnsavedChangesPlugin= {major: 3, minor: 3, revision: 3, date: new Date(2009,3,2)};
config.macros.unsavedChanges = {
changed: [], // list of currently unsaved tiddler titles
defMode: "panel",
defSep: " ",
defLabel: "There %1 %0 unsaved tiddler%2...",
defTip: "view a list of unsaved tiddler changes",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var wrapper=createTiddlyElement(place,"span",null,"unsavedChanges");
wrapper.setAttribute("mode",params[0]||this.defMode);
wrapper.setAttribute("sep",params[1]||this.defSep); // for 'list' mode
wrapper.setAttribute("label",params[1]||this.defLabel); // for 'command' mode
wrapper.setAttribute("tip",params[2]||this.defTip); // for 'command' mode
this.render(wrapper);
},
render: function(wrapper) {
removeChildren(wrapper); // make sure its empty
if (!this.changed.length) return; // no changes = no output
switch (wrapper.getAttribute("mode")) {
case "command": this.command(wrapper); break;
case "list": this.list(wrapper); break;
case "panel": default: this.panel(wrapper); break;
}
},
refresh: function() {
var wrappers=document.getElementsByTagName("span");
for (var w=0; w<wrappers.length; w++)
if (hasClass(wrappers[w],"unsavedChanges"))
this.render(wrappers[w]);
},
list: function(place) { // show simple list of unsaved tiddlers
wikify("[["+this.changed.join("]]"+place.getAttribute("sep")+"[[")+"]]",place);
},
command: function(place) { // show command link with popup list
var c=this.changed.length;
var txt=place.getAttribute("label").format([c,c==1?'is':'are',c==1?'':'s']);
var tip=place.getAttribute("tip");
var action=function(ev) { if (!ev) var ev=window.event;
var p=Popup.create(this); if (!p) return false;
var d=createTiddlyElement(p,"div");
d.style.whiteSpace="normal"; d.style.width="auto"; d.style.padding="2px";
// gather pretty links for changed tiddlers
var list=[]; var item=" [[%1 - %0 (%2 bytes)|%0]] ";
for (var i=config.macros.unsavedChanges.changed.length-1; i>=0; i--) {
var tid=store.getTiddler(config.macros.unsavedChanges.changed[i]);
if (!tid) continue;
var when=tid.modified.formatString('YYYY.0MM.0DD 0hh:0mm:0ss');
list.push(item.format([tid.title,when,tid.text.length]));
}
wikify("@@white-space:nowrap;"+list.join("<br>")+"@@",d);
if (!readOnly) {
var t="\n----\n";
t+="@@white-space:nowrap;display:block;text-align:center; ";
t+="<<saveChanges>>";
t+=config.macros.saveAs?" | <<saveAs>>":"";
t+=config.macros.upload?" | <<upload>>":"";
t+=(config.macros.emptyTrash&&store.getTaggedTiddlers("Trash").length)?" | <<emptyTrash>>":"";
t+=" @@";
wikify(t,d);
}
Popup.show(p,false);
ev.cancelBubble=true; if(ev.stopPropagation)ev.stopPropagation();
return(false);
}
createTiddlyButton(place,txt,tip,action,"button");
},
panel: function(place) { // show composite droplist+buttons+commands
// gather changed tiddlers (in reverse order by date - most recent first)
var tids=[]; for (var i=this.changed.length-1; i>=0; i--)
{ var t=store.getTiddler(this.changed[i]); if (t) tids.push(t); }
tids.sort(function(a,b){return a.modified<b.modified?-1:(a.modified==b.modified?0:1);});
// generate droplist items
var list=[]; var item='<option value="%0">%1 - %0 (%2 bytes)</option>';
for (var i=tids.length-1; i>=0; i--) {
var when=tids[i].modified.formatString('YYYY.0MM.0DD 0hh:0mm:0ss');
list.push(item.format([tids[i].title.htmlEncode(),when,tids[i].text.length]));
}
// display droplist, buttons, and command links
var out=''; var c=this.changed.length;
var NSP=config.formatters.findByField("name","nestedSliders");
var summary=this.defLabel.format([c,c==1?'is':'are',c==1?'':'s'])
out+=NSP?'+++(unsaved)['+summary+'|'+this.defTip+']...':(summary+"\n");
out+='<html><form style="display:inline"><!--\
--><select size="1" name="list" \
title="select a tiddler to view" \
onchange="var v=this.value; if (v.length) story.displayTiddler(null,v);"><!--\
-->'+list.join('')+'<!--\
--></select><!--\
--><input type="button" value="goto" onclick="this.form.list.onchange();">';
if (config.macros.loadTiddlers) {
out+='<input type="button" value="revert" \
title="import the last saved version of this tiddler" \
onclick="var v=this.form.list.value; if (!v.length) return; \
var t=\'<\'+\'<loadTiddlers [[tiddler:\'+v+\']] \'; \
t+=document.location.href; \
t+=\' confirm force noreport>\'+\'>\'; \
var e=document.getElementById(\'executeRevert\'); \
if (e) e.parentNode.removeChild(e); \
e=document.createElement(\'span\'); \
e.id=\'executeRevert\'; \
wikify(t,e);">';
}
out+='</form></html>';
if (!readOnly) {
out+='\n{{small nowrap{';
out+="<<saveChanges>>";
out+=config.macros.saveAs?" | <<saveAs>>":"";
out+=config.macros.upload?" | <<upload>>":"";
out+=(config.macros.emptyTrash&&store.getTaggedTiddlers("Trash").length)?" | <<emptyTrash>>":"";
out+='}}}';
}
out+=NSP?'===':'';
wikify(out,place);
}
};
// hijack store.saveTiddler() to track changes to tiddlers
if (store.showUnsaved_saveTiddler==undefined) {
store.showUnsaved_saveTiddler=store.saveTiddler;
store.saveTiddler=function(title,newtitle) {
if (title!=newtitle) {
var i=config.macros.unsavedChanges.changed.indexOf(title);
if (i!=-1) config.macros.unsavedChanges.changed.splice(i,1); // remove old from list
}
var i=config.macros.unsavedChanges.changed.indexOf(newtitle);
if (i!=-1) config.macros.unsavedChanges.changed.splice(i,1); // remove new title from list
config.macros.unsavedChanges.changed.push(newtitle); // add new title to END of list
var t=this.showUnsaved_saveTiddler.apply(this,arguments);
if (!this.notificationLevel) config.macros.unsavedChanges.refresh();
return t;
}
}
// hijack store.removeTiddler() to track changes to tiddlers
if (store.showUnsaved_removeTiddler==undefined) {
store.showUnsaved_removeTiddler=store.removeTiddler;
store.removeTiddler=function(title) {
var i=config.macros.unsavedChanges.changed.indexOf(title);
if (i!=-1) config.macros.unsavedChanges.changed.splice(i,1); // remove from list
this.showUnsaved_removeTiddler.apply(this,arguments);
if (!this.notificationLevel) config.macros.unsavedChanges.refresh();
}
}
// hijack store.setDirty() function to reset change list after file save
// note: do NOT hijack the prototype function. This hijack should only be applied to
// the main 'store' instance only (i.e., don't refresh when loading temporary store
// as part of ImportTiddlers processing)
if (store.showUnsaved_setDirty==undefined) {
store.showUnsaved_setDirty=store.setDirty;
store.setDirty = function(flag) {
var refresh=this.isDirty() && !flag; // 'dirty' to 'clean', force a refresh...
this.showUnsaved_setDirty.apply(this,arguments); // but change the flag first.
if (refresh) {
config.macros.unsavedChanges.changed=[]; // clear changed list
config.macros.unsavedChanges.refresh();
}
}
}
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 29/05/2009 12:26:06 | ELS | [[/|http://lumpymilk.tiddlyspot.com/]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . |
| 29/05/2009 17:29:36 | ELS | [[/|http://lumpymilk.tiddlyspot.com/]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . |
| 10/08/2009 01:15:01 | YourName | [[/|http://lumpymilk.tiddlyspot.com/#howl.com!]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . | failed |
| 10/08/2009 01:15:27 | YourName | [[/|http://lumpymilk.tiddlyspot.com/#howl.com!]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . | failed |
| 10/08/2009 01:15:48 | YourName | [[/|http://lumpymilk.tiddlyspot.com/#howl.com!]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . | failed |
| 10/08/2009 01:16:26 | YourName | [[/|http://lumpymilk.tiddlyspot.com/#howl.com!]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . | ok |
| 10/08/2009 01:19:10 | YourName | [[/|http://lumpymilk.tiddlyspot.com/#howl.com!]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . |
| 10/08/2009 01:20:16 | YourName | [[/|http://lumpymilk.tiddlyspot.com/#howl.com!]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . |
| 16/08/2009 17:45:04 | YourName | [[/|http://lumpymilk.tiddlyspot.com/]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . |
| 03/12/2013 08:33:03 | YourName | [[index.20131203.0827180000.html|http://lumpymilk.tiddlyspot.com/_sites/l/lu/lum/lumpymilk/backup/index.20131203.0827180000.html]] | [[store.cgi|http://lumpymilk.tiddlyspot.com/store.cgi]] | . | [[index.html | http://lumpymilk.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
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;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<span class='title' macro='view title'></span>
<span macro='tiddler AddANote if:{{!readOnly && store.tiddlerExists(story.findContainingTiddler(place).getAttribute("tiddler")) && tiddler && tiddler.tags.containsAny(["annotate", "bookmark", "journal", "blog"])}} with: {{tiddler?tiddler.title:""}}'></span>
<div class='subtitle fine'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagClear'></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<div class='toolbar' style='line-height:100%;margin-top:.5em;'><a href="javascript:;"
onclick="window.scrollTo(0,ensureVisible(story.findContainingTiddler(this)));return false;"
onmouseover="this.title='scroll to top of '+story.findContainingTiddler(this).getAttribute('tiddler')">▲</a>
</div>
<div class='tagClear'></div>
<!--}}}-->
<<tiddler HideTiddlerTags>><<tiddler HideTiddlerBackground>><<tiddler ReplaceTiddlerTitle with: [[\x22Portable blogging... anytime, anywhere!\x22]]>>
<<<
~TiddlyBlog combines tiddler journals, with StorySaverPlugin, MiniBrowser, FAQViewer, CalendarPlugin, QuickEditPlugin, and other [[TiddlyTools|http://www.TiddlyTools.com/]] power tools, to provide a ''completely portable, self-contained blogging environment''.
Whether you are capturing your personal musings, favorite links, and collected poems/jokes/stories, or using it as a research tool to record experiments/field studies, along with notes/reference data, and links to outside resources, you can simply ''copy your tiddlyblog onto a USB stick and take it with you wherever you go!''
Or, share your tiddlyblog with friends, family, co-workers, clients, etc. simply by ''sending it as a file attached to an email message''. In addition, the TspotSetupPlugin and related supporting plugins are already installed in the document, so that you can quickly ''publish your tiddlyblog online using a [[free TiddlySpot account|http//www.TiddlySpot.com]]''.
<<<
/***
|Name|WikifyPlugin|
|Source|http://www.TiddlyTools.com/#WikifyPlugin|
|Documentation|http://www.TiddlyTools.com/#WikifyPluginInfo|
|Version|1.1.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|substitute fields, slices, or computed values into a wiki-syntax format string and render results dynamically|
The {{{<<wikify>>}}} macro allows you to easily retrieve values from custom tiddler fields, tiddler slices, computed values (using javascript) or just plain old literals, and assemble them into small bits of generated wiki-syntax text content that can be rendered directly into a tiddler, or used in the ViewTemplate or EditTemplate to add dynamically-generated content to each tiddler.
The {{{<<wikiCalc>>}}} macro performs the same processing as {{{<<wikify>>}}} and, in addition, passes the assembled text content through javascript's {{{eval()}}} function before rendering the results. This allows you to, for example, construct and compute mathematical expressions that use input values extracted from tiddler fields or slices.
!!!!!Documentation
> see [[WikifyPluginInfo]]
!!!!!Revisions
<<<
2009.03.26 [1.1.3] unescape output before wikify so that \n can be used in formatting string
|please see [[WikifyPluginInfo]] for additional revision details|
2007.06.22 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.WikifyPlugin= {major: 1, minor: 1, revision: 3, date: new Date(2009,3,26)};
config.macros.wikify={
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var fmt=params.shift();
var values=[];
var out="";
if (!fmt.match(/\%[0-9]/g) && params.length) // format has no markers, just join all params with spaces
out=fmt+" "+params.join(" ");
else { // format param has markers, get values and perform substitution
while (p=params.shift()) values.push(this.getFieldReference(place,p));
out=fmt.format(values);
}
if (macroName=="wikiCalc") out=eval(out).toString();
wikify(out.unescapeLineBreaks(),place);
},
getFieldReference: function(place,p) { // "slicename::tiddlername" or "fieldname@tiddlername" or "fieldname"
if (typeof p != "string") return p; // literal non-string value... just return it...
var parts=p.split(config.textPrimitives.sliceSeparator);
if (parts.length==2) {// maybe a slice reference?
var tid=parts[0]; var slice=parts[1];
if (!tid || !tid.length || tid=="here") { // no target (or "here"), use containing tiddler
tid=story.findContainingTiddler(place);
if (tid) tid=tid.getAttribute("tiddler")
else tid="SiteSlices"; // fallback for 'non-tiddler' areas (e.g, header, sidebar, etc.)
}
var val=store.getTiddlerSlice(tid,slice); // get tiddler slice value
}
if (val==undefined) {// not a slice, or slice not found, maybe a field reference?
var parts=p.split("@");
var field=parts[0];
if (!field || !field.length) field="checked"; // missing fieldname, fallback: checked@tiddlername
var tid=parts[1];
if (!tid || !tid.length || tid=="here") { // no target (or "here"), use containing tiddler
tid=story.findContainingTiddler(place);
if (tid) tid=tid.getAttribute("tiddler")
else tid="SiteFields"; // fallback for 'non-tiddler' areas (e.g, header, sidebar, etc.)
}
var val=store.getValue(tid,field);
}
// not a slice or field, or slice/field not found... return value unchanged
return val===undefined?p:val;
}
}
//}}}
//{{{
// define alternative macroName for triggering pre-rendering call to eval()
config.macros.wikiCalc=config.macros.wikify;
//}}}
data://image/jpeg;base64,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
data://image/jpeg;base64,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
data://image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMAEAMCAwYAAAQgAAAKnAAAERv/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoXHh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoaJjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAPABQAMBIgACEQEDEQH/xACYAAEBAQEBAQAAAAAAAAAAAAABAAIDBAYBAQEBAQAAAAAAAAAAAAAAAAABBAUQAAIDAQACAgIDAQEAAAAAAAABEQISIRAiAxMwMSBQI0BwEQACAgECBQMDBAMAAwAAAAAAASExERBBgZGhAjJRcbEgYeHB0fESMCJC8JIDEgAABQUAAAAAAAAAAAAAAAAAEEBBUVBwgAEx/9oADAMBAAIRAxEAAAD6WXnaxlDPTBWVdIoZ0Brno2MApzOmK042MkRrQZ2AajK5EoYQNRh1BnoAmTpYTTzDscw6ZwFrKuwksoZWpcsuqUtUUQxoDWQaFwpULVo5jLh3Jh2LlQlkKSkA6RzOsc3pGFioTecqoBaEYwdM5QqCaiaGZSZC0BayKBqyHQ5p0eeyEJsm7nHTXPSaxZXVlN5hMm1cOw5uozbyCImqzGesvJcxqIs7AztXm6A1nSa1iNRoJkFAGUSNvMs6vFjYQuYc6qzbCihBUoLO4528rLFUgsFtMOwyqmbUc7cuWUGQzvJRLqyiQi5Su2Tksuc6glM2os6jMpl0EylQaDRk1GbYGpM56Jzz2yYOic3cYtJh3BZDRkXQBootYDqc46nPRqyGtYjVlFzGnMmnMbsJsKxspoMy9LnJqG0gjUFOTMq5jTlGIc6gQNEGjQFqoNQW8oNSwyW86qECQnKMQxGRTFSlBsKNQ0NkSYoaqC1mjRRNUGwzo0FQtIlEayUwIHMVRQOmaEI1rk10MUQVNQWkyqYtQMgwMRt5ybCXRmKg0ZjRmNmWKimpRVCqJy0uY2ZDqc2NgDjSZ1FIplg0SE6CaMmisWoEozaqyiskJEacVbsqUUINFpMswS1m3RlqlzRuyG7k1siDOysW0wdCMOmuV1jOtMYOsnA9AvG0Vm6aji9M0WsjZpdWZNBK6zJt56rZkjQQZ6FZmIgrSZqLWSXrclOthJA1c03CRQGgylW3kxvNVZ3GHcYx2jLURqBSoQxreT//2gAIAQIAAQUA/k1/Rz/5BP8Axd/qZJ/4OeJ/nP8ACPxf/9oACAEDAAEFAP6+SSf+GPMEfyn+kn8E/mkkkkknxH5I8wR/Tc/FH9zJJP4o/DHiER+b/9oACAEBAAEFAJZlsVYIY6mWQTArLw11rumhWOPw+jpJloVoaaZk6SNoTRKaw5gxZi+NIiiHgnmnG2h/JVn2Cd0fsaSaIYlA3I0yLCqQQfobHLaRVD/S6cG4GmyqSKvnSGZMkHDnmHMMgymYRgyyBrxliRkyKplCpVmUcTmrHkaSKiskanw7pEtiViEJpG0bkVmdOkHEaRobZ0UskhkdbRzw2ShscivB9lT7Ex2Sf2D+RCY3Zi0RYhkEKWqkksSsxVFRCSPVCdTaPZmEJJHDSl3Nc05m0OrZDRpCdSbMaZEmSBIggyxVZkwRA4IIkgRAq8+sXxoXx1Riqeao4iEh2JbE0NoTUuB3SHc2zdjV2ex7DREiTOiTIfjgskLwkZMIwj66n1oXxmYModUZZ1Esc+G2zrEfsyy9siTY0hyI4cOEEWIIIIRlECVSKnqcJR6kVFVEWQ1c9yfkFdjY20K0lYZ6jJUVaEh6Rr5GKktIaQ4FBI7HWQ2QJM6jpDIsQxqyfsdIHJ0kViSUSaGutMTEyUODVUcaSTUQZZCFShmg0YMEIZ7SoHVjqhyiWhMRkasNvw1Jw6RYhikTgVqjyTUzUyhNIlEo9WLI0KSIOMSG2ag2hWTIHVMVXCpB0ehWZpy0xEwbU6GxEeIkzLSJab2J/IiWhps9z2lyxyNtnEOyRNWcNGqwrEskUy1aUrEsevDgzUcksVmObLNjqEcF0gaFUyxVgyLJCZCRCYqoaqZ6qmGJNiV59xqxFhNjVmJNE2G2TUSG2aQ7IToNobR6idYmo0iJFWp6o0iUOyZ6CgeULMNEEIjqRwyh0UtfGKtUbXh9GkxQlqppGkO1WLI7Iw2ZsYY6Np1YumR1IEkIgaZDYqshiTEiOwQxpE1Q9HRWcJWZlxDIQqqWhQKrYqwZHSDMioj66kVSeWOtV4ixFyLC0ibEfIP7B6iLC0ZY62Qk2dHJ7C0KT2lK7cMbshbPYabEhyTHieIbITFWreazmppI0aY2iRzM+IgSIZkiEQiSBDTYlWX+0erJ5HZRriZ0eibIls0bQrSdE2S0NibFkdrDtA7MVkLLbpUdWT8iNCaayJXJuN2RpDskJ1ZqpxkMSsdPbwjviUJECTaba8S0cYhtw/1KRHyENDUjgymYZiyErHRbHBFZzRHDLIdRtn+kRYgbRn4xVpCVTKEqnqjdRWTFLLJCtDlTAtDVmQ4hEMavEUIqNUQ3Q1VGpJszTRtsmBWJrM1Q7VZFWKinNRKp0ixFhbPYehaJaJJQrQK7HY12WTU9Cak0JoifjIoxpx7jdkOzQ2mKCEQpzzEipBCTgcicCPZEisaJOCaHHhtyrcVmbNiubsaaJTJqhNMacLR7HRfJQd0x2cu6Y3UVkxi0iWySSWjUktnsTZDtBrruTyRWklMmDQ4YqoihFRVozNDJlEQIfxyQfpO/Psht/IK+TVWTxK6E2STAnVnqfsaTHUSSJqx6PY0yWxJy8iaErMlo1UVkSkaRI5HZITR0asK90K1h2NJjqmNWOIVkMSgVoE6MdUPZ9kPdLESPXjLIshoSOCVCaknDFTNTMEkpHGOrQl8iE2N1M/CzNTNibo1Vk0ZKRKZMmTqNXNE1YmjrFozVirRHqcEmRZmWZsQ0ex0co+xJq1WSe402KkiUEsbQ2hXSekyYG0yDhKJkUx6zwhsYnWE0dZA1JlEoQ2xOxI7I0hMmxLFYbTHSrPrgSuj/AEN2FeorfGz1E0jVSak2NWHeD7DY3UmpFpiRJCbRpkomqHliq2RZCtYdrDvJPxsxUdbImx6sVambI/0QoZNU/ViYrMmzPclmu6JRKGkRYZw4iUhH10H8bP0+jRwbkaZw1BqxoleIgWzR6GBUsj/RCtZH2VNVPSW6H+ZFCKkJDE2TY1Yl+E0cPUdasn5DPysfx3EroSsKo6Jn1DrZEsipnnt4lCY58yiVLshNjbE2mmK6NoV0O6NVZmrTSRutRfOL5mx/IfZ8jE/mZ/r/AAhC8x4cj+OzPqumqtGajVUTU/zM0IRDIsTcRNRMlCfZNobTOM6iX4ijMIavUd3Nbrxm6NMV0KwmSTzRpiuz7Wfcz7rH23Zu43YasZsYtKrZeODgcDskO4k2ZY6shpw/PsJoirFtFn8h6ipJ7Es9WOpNkK5o/fhps/RKQmjpqxLY20P5Ej7JHdmnKdmZvGGYgzUXBtmkxocChiTTixDMsaQkxSx5Z//aAAgBAgIGPwBZNvnrjDmihH//2gAIAQMCBj8Aws//2gAIAQEBBj8Aj6vR6wTpOmSdYMMkyuBBWsM9SkXhF6bkPPQnWEXhfTRRlE/58blY+5Jn67Jb+xuTkoorJ44K03+nD/w1pjRfTX1wpFt6ll6XzP5NzcjLJRGkssvob9Tcp9CO3BRtgllkss9SEUZ0kxrB6fQ9yeGlFH4JJNzctn502Mfob6ykUiikUjY2NiyyWWb8yslGDC+nYxjSzcp8z04ll8kblGcFLOllksvSyP8AB6lG5BRuXrgjT2Pgy2/Yyj9yWjYvSskssvSclFFI2KKK0tkNkMhrkWuROD+TNcSFniT2/BRTMy0UU+BlIwlplvL0l4N2SioI7SkQ0Qvo2PybFIk2Ni0WSyO48kWtMEElo2IfyXgnPUyq4kGMk5Z/JkrSz1KIMuC2/Uho2PwzLyzc3MybkxwL+SO4w8shczZEs8vgnuILfIvoT3dDP9uh5EdxLIbNyE+ZieZOkNlvkS3yL5ogj9SMFpcCWmzyXItcEff2Ja5GX3IvkWzc3LMTyIybs3PFmMGMEYRODYnBDXUy8EtFotHkeT6E9zI7m+LMNstlst4LZ5fBHeuKM5Ra+55dpsT3JEd2WW37It8iMrgX0LZvknJubm/M3RuQnzMtMzhvieJj+rRj+rKZXMrHsY/rn3PEjtRjCRsWjbPAy2sGMoxlFo2Jwi+3ij/k2KRh9qPFMrHMrqfkmOJ+Sz8mxRSK+SvklfJWn5I+SU+hubktlsy2ye543P5MyYw8aUzxyZx1M4RmEj1KRCRRC4k9dNy/gnPI3LfIxJvyN+R+Dctm5uWy2b8iM8tJIs9C59z8l9SWX10lSRgrofgk36GZK4ksvTBCbPEhIpErTEGxsbMk9C0Q0TjScEYLRsUSoMJEduTxwV1KKxyN+h4voZwyimbkpMzjWOpsXBGkOPvrkznBsSQSZwj0InT0MlIo30zktl6QWTJGNY0hEpkE5IT5FPieKNkPOnoRJKy/sSiDKIZRXIlNG690WWWQ8EvTY25js/Olnl8ENvkW1yLybmL5GxRR4sw0y0+Gk/rrBM6QfYolY9i2YXczyfItMjDKTJ7eWDxbKa6mcfJXyQWWzyPIjuLyXgw2eZHeeSPLkWeTR5YPJcjGW+ZbXM82S2+B/r1J+TcvoSzbmentJvy0n4Lx7Gf7czOSO740tFotE46mV+uk6UQvgr4KZTKJ7Tw6Hi+RK6Mj9dLfA3K6mHjmfgm/YnBmCEzcjWF8n8kG56lE/Bj9Cs8DOEuBgjjZH6k/JvzN+hb5E9z/APU8ujLXJlrqT/Vm3Aj9T+UU+Zv0NyzcttcCU2ZS45aMb+5ifc+3sT+p/OjwycdCPlErlgpk/Bn9yGuYqfsyIJMafcrJJEn8GJIbN+Z5MshmW38GJLLyS8G3cjH9ORGVxMJ/Gkl6wUupsuLLzxPTgiI4Gz5kp8GYy17otM8OR4tPiW0X0Ja4l9vUh9vU8u08u3geSJ7kuBh9y98IjvXQtFkpYN17OCc+5bM5ZHdzJ7keRsyp9jDSKwZXc0Q0/c/27cEEM9SUQ2ThmTM6Suh/qV8m3U/LIM5fQ36Ep8kRjkQ1yK7GiexE9uF6l4I7yGmT2x9icovmR3HkbGxGDZk9p6e5HcQ0VkntIyi2X0PLPAtci0bG3U/56lLgR29SVhl9SD1JRui8+5sSj0J7s/YpM8TwfAj+yJb4o8uhDXItGxHyf+MntKaLZDQoR4kprmf9dTya9y1xJwzx6lNFkd2WZKZZJ6GV3FrBWSUzDLwR3Hki0UiEyUymblZ5FPkXzM2ijchkpM8WvY34logtlribMlEohkSiiUQ+pHdzM4TJ7Wi2iO4tFohLmUmeJ4niyuhsQV1K6lMt9TyLN0f6tmH3GxPabo8iFkp5+xb4mzJ7eRfPTKZ6koojSSUYwUePQ8Oh44KI+T0I7jyLzyKyVgkxJbJkohItInBZLL4HiQ8HqSiyD1MtFtEMnGu5fyWX+ukpFdSiitJSI0tlt8GeLa9iP/m8kdh4lLoZ+DCz9FfR9yiIJWSmUz8H4LIeeJeCHklIlNaWbH7G/Mln7EGEySVnkVj2I7sHqSfuZrSVrf1VpBRRKKKKJbJxrXM2IRn4MZPU9Bbk6ymZzghruXUlEwZ7XyIcErSGev0Y0nTOtk5NyEyFphFk6bkZ5EwbcyiUf6508SmbkkEyVg//2Q==
/%
URL:http://crapules.tv/chumby/ZenMaker.swf
Description: What is the sound of one mouse clicking?
Author: unknown
%/{{center big{click on the glowing spheres...}}}
//{{{
// set readOnly to true or false in each of the following lines...
readOnly=false; // default for all visitors
if (document.location.protocol=='file:') readOnly=false; // local editing
if (config.options.txtUserName=='ELS') readOnly=false; // you!
config.options.txtMaxEditRows="20"; // TW core option
config.options.chkInsertTabs=true; // TW core option
config.options.chkShowLeftSidebar=true; // ToggleLeftSidebar
config.options.chkShowRightSidebar=false; // ToggleRightSidebar
config.options.chkStoryFold=true; // StorySaverPlugin
config.options.chkSliderunsaved=true; // UnsavedChangesPlugin
//}}}
<<tiddler HideTiddlerTags>>/%
Description: howl.com (with apologies to Allen Ginsburg)
%/@@display:block;width:80%;margin:0 auto;{{center medium{
{{big{howl.com!
By Thomas Scoville}}}
//(with apologies to Allen Ginsberg)//
(orginally appeared 3/22/2000 on salon.com
re-posted with permission of the author)
I saw the best minds of my occupation destroyed by venture capital, burned-out, paranoid, postal,
dragging themselves through the Cappuccino streets of Palo Alto at Dawn looking for an equity-sharing, stock option fix,
~HTML-headed Web-sters coding for the infinite broadband connection to that undiscovered e-commerce mother lode in the airy reaches of IP namespace,
who poverty and ripped Yahoo tee shirts, cubicle-eyed and wired on Starbucks sat up surfing in the virtual ether of one-million-dollar, one-bathroom condos next to the railroad tracks, skipping across the links of killer Web sites contemplating ... Java,
who rammed their brains into compilers and saw Intel angels staggering on microchips under the insane weight of investor expectation,
who blew off the search for Truth for as-yet-undreamed New Economy scams, business models hallucinating infocapitalist messiahs on clouds of market cap,
who abandoned lucid dreams of a Better Way for Shockwave fluff and ~RealAudio baubles dangling from the buggy venality of digital commerce,
who, while haunted by the scowling ghosts of hackers past -– Stallman, Nelson, Engelbart –- auctioned their immortal souls on eBay, with documentation and a full year of support included, of course,
who got busted in their spotless Nike cross-trainers traveling through cyberspace with a file of illegal crypto for Open Source,
who ate sushi in Austin or drank microbrews in Silicon Alley, jousting with bad mojo funk of layoffs, Chapter 11, or diluted company stock night after night,
who chained themselves to start-ups for the endless ride from San Jose to Wall Street on adrenaline and Evian, laptop batteries flaming out over Oklahoma, no more vegetarian entrees, sir, would you like the latex omelet instead?
endless nights of keyboard grinding and corporate microwave popcorn and Jolt Cola until the noise of their own deadlines brought them down, gawping, convulsing, mute, crushed beneath their own project plans,
who talked continuously about convergence and distributed control and cluetrains and ~Y2K and extropians and Libertarians and Microsoft and Linux and slashdot and wouldn't fucking shut up,
who pointed their browsers at Red Herring and Slate and Salon.com hoping against hope that somebody might be able to make sense of the infinitely perverse, ball-busting, soul-scorching, silicon-supernova black hole that kept them awake all night every night and wouldn't let them alone long enough to find dates in this lifetime,
who tattoo'd and pierced and dyed and branded themselves in a desperate act of self-mutilating cyber-hepster cool, all the while wearing a suit and tie on the inside they could never, ever take off, and praying nobody would find out about the MBA,
who renounced the smokestack relics, the old guard and their father's Oldsmobile only to find that they had been replaced by artifacts even less substantial,
who chanted the free market mantras of laissez-faire and techno-darwinism and Adam Smith's invisible hand-job except when Big Bad Bill the Bully Gates-of-hell came to take away their lunch.com -- and became Socialists of Convenience.org,
who stalked investment bankers through Bistros and wine bars and martini lounges, begging pleading groveling for one more hit of funding from the luminous check-book oh please oh please oh please
ah, Bill, you are not safe, I am not safe, and now we languish in the dot com pressure cooker hoping for one last buzz of the old hallucinations.
The wrecked avenues, the sullied conduits, the pinched pipes of a quadrillion dropped and ruined packets.
The world wide waits, the denials of service, the infinite hosts of hardcore farm-animal boredom, ghoulish domain-name squatters jumping out from behind every virtual tree.
These failed revolutions, these paradigms lost, the end of Web Time, and P/E ratios good to last the next thousand years.
Dot com! Dot com! Dot com!
forever, and ever, ka-Ching.
}}}@@