Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
/***
|Name|AdvancedOptionsPlugin|
|Source|http://www.TiddlyTools.com/#AdvancedOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#AdvancedOptionsPlugin|
|Version|1.2.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.3|
|Type|plugin|
|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.
This plugin also extends the standard {{{<<option>>}}} macro syntax so you can directly set the internal value of a boolean or text option, without displaying a corresponding checkbox or input field control simply by appending {{{=value}}} syntax to the end of the option ID parameter:
{{{
<<option "txtSomeOption=some text">>
<<option chkSomeOtherOption=true>> OR <<option chkSomeOtherOption=false>>
}}}
Example: {{{<<option chkAnimate=false>>}}}
<<<
!!!!!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
<<<
2009.07.23 [1.2.0] added support for enhanced {{{<<option id=value>>}}} 'direct assignment' syntax
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: 2, revision: 0, date: new Date(2009,7,23)};
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");
}
//}}}
//{{{
config.macros.option.AOPsave_handler=config.macros.option.handler;
config.macros.option.handler=function(place,macroName,params,wikifier,paramString,tiddler) {
var parts=params[0].split('=');
if (parts.length==1) return this.AOPsave_handler.apply(this,arguments);
var id=parts[0]; var val=(id.substr(0,3)=='txt')?parts[1]:(parts[1]=='true');
config.options[id]=val;
}
//}}}
!usage
{{{<<player flash AnalogClock 400px 400px>>}}}
<<player flash AnalogClock 400px 400px>>
!notes
{{{<<player>>}}} macro requires http://www.TiddlyTools.com/#PlayerPlugin
!type
application/x-shockwave-flash
!file
./clock.swf
!url
http://www.TiddlyTools.com/clock.swf
!data
/***
|Name|AnimationEffectsPlugin|
|Source|http://www.TiddlyTools.com/#AnimationEffectsPlugin|
|Documentation|http://www.TiddlyTools.com/#AnimationEffectsPluginInfo|
|Version|3.1.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.2|
|Type|plugin|
|Description|display content with timer-based animations to manipulate multiple CSS attributes|
|Status|!BETA - EXPERIMENTAL - UNDER DEVELOPMENT - USE WITH CAUTION|
This plugin defines the {{{<<animate>>}}} macro that can be used to peform simple animations of formatted tiddler content by saving/setting/reseting the values of CSS style attributes at specified times. The macro can also be used to smoothly animate CSS styles that use ''numeric values'', by automatically computing a series of incremental values, ranging from //start// to //stop//, for a specified //duration//, with optional "pause-and-reverse" //cycles// to create repeating animations or continuous loops.
!!!!!Documentation
>see [[AnimationEffectsPluginInfo]] for macro syntax
>see [[AnimationEffectsSampler]] for a live animation example...
!!!!!Revisions
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to [[AnimationEffectsPluginInfo]]
2008.01.07 [3.1.1] when animation is disabled, set inner container to original DIV/SPAN
2007.12.16 [3.1.0] added support for "add/remove" classname functionality. Also, in handling for "set", only stored previous attribute value if not already saved and, on "reset", clear saved value. This blocks animations from inadvertently overwriting the saved value while simulaneously processing animation sequences that act on the same attribute.
2007.12.08 [3.0.0] Combined ZoomTextPlugin and AnimateTiddler inline script into single plugin
2007.08.03 [2.1.0] converted from ZoomText inline script
2007.07.16 [2.0.0] added TW2.2-compatible Morpher handling for smoother animation on slower systems
2007.02.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.AnimationEffectsPlugin= {major: 3, minor: 1, revision: 1, date: new Date(2008,1,7)};
config.macros.animate = {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var id=new Date().getTime()+Math.random().toString(); // globally unique ID (GUID)
if (params[0] && (params[0].toUpperCase()=="DIV"||params[0].toUpperCase()=="SPAN"))
var nodetype=params.shift().toUpperCase(); // optional param to force DIV/SPAN
var src=params.shift(); if (!src) src="="; // content is first parameter (if no params, animate container)
if (src.substr(0,1)=="=") { // content=DOM element... use "=here" or "=" (without ID) for current container
var target=place;
if (src.length>1 && src.substr(1).toUpperCase()!='HERE') target=document.getElementById(src.substr(1));
if (!target) return; // couldn't locate target element... do nothing.
var nodetype=nodetype||target.nodeName.toUpperCase();
} else { // use content from tiddler or "inline" param
if (src.substr(0,1)=="@") src=store.getTiddlerText(src.substr(1)); // "@TiddlerName"
var nodetype=nodetype||"span";
var target=createTiddlyElement(place,nodetype);
wikify(src,target);
}
if (params[0]) switch(params[0].toUpperCase()) {
case "SAVE":
var s=params[1]; if (!s) return; // must specify style attribute
if (s.substr(0,1)=="+") s=s.substr(1); // ignore leading "+" (if any)
var w=(params[2]!=undefined && config.options.chkAnimate)?parseInt(params[2]):0; // wait time before saving
if (!target.savedStyle) target.savedStyle={};
if (target.savedStyle[s]!==undefined) return; // value already saved... do nothing.
if (!w) { target.savedStyle[s]=target.style[s]; return; } // save style immediately... done.
target.id=target.id||id; // use existing ID if target has one, otherwise assign GUID
var fn='var e=document.getElementById("'+target.id+'"); \
if(e&&e.savedStyle["'+s+'"]==undefined) \
e.savedStyle["'+s+'"]=e.style["'+s+'"]';
setTimeout(fn,w); return; // timer is set... done.
case "SET":
var s=params[1]; if (!s) return; // must specify style attribute
if (s.substr(0,1)=="+") s=s.substr(1); // ignore leading "+" (if any)
var v=params[2]!=undefined?params[2]:""; // value to set
var w=(params[3]!=undefined && config.options.chkAnimate)?parseInt(params[3]):0; // wait time before setting
if (!w) { target.style[s]=v; return; } // set style immediately... done.
target.id=target.id||id; // use existing ID if target has one, otherwise assign GUID
var fn='var e=document.getElementById("'+target.id+'");if(e)e.style["'+s+'"]="'+v+'"';
setTimeout(fn,w); return; // timer is set... done.
case "RESET":
var s=params[1]; if (!s) return; // must specify style attribute
if (s.substr(0,1)=="+") s=s.substr(1); // ignore leading "+" (if any)
var w=(params[2]!=undefined && config.options.chkAnimate)?parseInt(params[2]):0; // wait time before reset
if (!w && target.savedStyle && (s in target.savedStyle))
{ target.style[s]=target.savedStyle[s]; target.savedStyle[s]=undefined; return; } // reset style immediately
target.id=target.id||id; // use existing ID if target has one, otherwise assign GUID
var fn='var e=document.getElementById("'+target.id+'"); \
if(e&&e.savedStyle&&("'+s+'" in e.savedStyle)) \
e.style["'+s+'"]=e.savedStyle["'+s+'"]; e.savedStyle["'+s+'"]=undefined';
setTimeout(fn,w); return; // timer is set... done.
case "ADD":
var add=true; // fall-through for further processing
case "REMOVE":
var c=params[1]; if (!c) return; // must specify a classname
if (c.substr(0,1)=="+") c=c.substr(1); // ignore leading "+" (if any)
var w=(params[2]!=undefined && config.options.chkAnimate)?parseInt(params[2]):0; // wait time before setting
if (!w) { (add?addClass:removeClass)(target,c); return; } // add class immediately... done.
target.id=target.id||id; // use existing ID if target has one, otherwise assign GUID
var fn='var e=document.getElementById("'+target.id+'");if(e)'+(add?'addClass':'removeClass')+'(e,"'+c+'")';
setTimeout(fn,w); return; // timer is set... done.
}
// remove old containers before RE-animating, unless combining effects (using "+style" param)
if (params[0] && params[0].substr(0,1)!="+") cleanup(target);
function cleanup(here) { // recursively finds all animation containers
if (here.childNodes) for (var n=0; n<here.childNodes.length; n++)
if (here.childNodes[n].className=="animationContainer") cleanup(here.childNodes[n]);
if (here.className=="animationContainer") { // move content up a level and remove container
var e=here.firstChild;
while (e) { var next=e.nextSibling; here.parentNode.insertBefore(e,here); e=next; }
removeNode(here);
}
}
// create animation outer "clipping" container and inner "formatting" container
var outer=createTiddlyElement(null,nodetype,null,"animationContainer");
outer.style.overflow="hidden";
var inner=createTiddlyElement(outer,nodetype,id,"animationContainer");
inner.style.position="relative"; inner.style.lineHeight="100%";
target.insertBefore(outer,target.firstChild);
// move content elements into the inner container
var e=target.firstChild.nextSibling;
while (e) { var next=e.nextSibling; inner.insertBefore(e,null); e=next; }
// params and defaults for morph
inner.OriginalType=target.nodeName.toUpperCase(); // SPAN or DIV
inner.What=params[0]?params[0]:'left';
if (inner.What.substr(0,1)=="+") inner.What=inner.What.substr(1); // trim off "+" prefix (if any)
inner.Format=params[1]!=undefined?params[1]:'%0%';
inner.Start=params[2]!=undefined?parseInt(params[2]):100;
inner.Stop=params[3]!=undefined?parseInt(params[3]):0;
inner.Wait=params[4]!=undefined?parseInt(params[4]):0;
inner.Duration=params[5]!=undefined?parseInt(params[5]):2000;
inner.Cycle=params[6]!=undefined?parseInt(params[6]):1
inner.Pause=params[7]!=undefined?parseInt(params[7]):0;
if (!config.options.chkAnimate) { // if not animating
if (inner.Cycle && (inner.Cycle % 2)) inner.Start=inner.Stop; // odd # of cycles: apply ending value
inner.style.display=inner.OriginalType!="DIV"?"inline":"block"; // restore original display style
var outer=inner.parentNode; if (outer && outer.parentNode) // remove outer clipping container
{ outer.parentNode.insertBefore(inner,outer); removeNode(outer); }
}
inner.style[inner.What]=inner.Format.format([inner.Start]); // set initial style value
if (inner.What=="fontSize" && inner.Start<=0) inner.style.display="none"; // hide text if initial size is 0
if (config.options.chkAnimate) setTimeout("config.macros.animate.morph('"+inner.id+"')",inner.Wait); // ANIMATE!
},
//}}}
//{{{
// animation 'tick' handler (timer callback)
morph: function(id) {
var inner=document.getElementById(id); if (!inner) return;
var p = [{style: inner.What, start: inner.Start, end: inner.Stop, template: inner.Format}];
var c = function(inner,p) { // reverse and re-animate until cycle count==0 (use -1 for continuous looping)
if (inner.Cycle==0 || inner.Cycle==1) {
// finished animation... discard outer container but keep inner container to display final style(s)
inner.style.display=inner.OriginalType!="DIV"?"inline":"block"; // restore original display style
if (p[0].style=="fontSize" && p[0].end<=0) inner.style.display="none"; // hide text if final size=0
var outer=inner.parentNode; if (outer && outer.parentNode) // remove outer clipping container
{ outer.parentNode.insertBefore(inner,outer); removeNode(outer); }
}
else { // reverse-and-repeat
inner.Cycle--; var t=inner.Start; inner.Start=inner.Stop; inner.Stop=t;
setTimeout("config.macros.animate.morph('"+inner.id+"')",inner.Pause);
}
};
inner.style.display=inner.nodeName.toUpperCase()!="DIV"?"inline":"block"; // show starting content
anim.startAnimating(new Morpher(inner,inner.Duration,p,c));
}
};
//}}}
//{{{
// for backward-compatibility with retired [[ZoomTextPlugin]]
config.macros.zoomText = {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
// convert old params to new params and invoke new handler
var Text=params[0]!=undefined?params[0]:"";
if (Text.substr(0,1)=="@") Text=store.getTiddlerText(Text.substr(1));
var Wait=params[1]!=undefined?parseInt(params[1]):0;
var Start=params[2]!=undefined?parseInt(params[2]):1;
var Stop=params[3]!=undefined?parseInt(params[3]):100;
var Duration=params[4]!=undefined?parseInt(params[4]):config.animDuration;
var Cycle=params[5]!=undefined?parseInt(params[5]):0
var Pause=params[6]!=undefined?parseInt(params[6]):0;
var newParams=[Text,"fontSize","%0%",Start,Stop,Wait,Duration,Cycle,Pause];
var newParamString=["[["+Text+"]]","fontSize","%0%",Start,Stop,Wait,Duration,Cycle,Pause].join(" ");
return config.macros.animate.handler(place,macroName,newParams,wikifier,newParamString,tiddler)
}
}
//}}}
/***
|Name|AnimationEffectsPlugin|
|Source|http://www.TiddlyTools.com/#AnimationEffectsPlugin|
|Documentation|http://www.TiddlyTools.com/#AnimationEffectsPluginInfo|
|Version|3.1.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.2|
|Type|documentation|
|Description|documentation for AnimationEffectsPlugin|
|Status|!BETA - EXPERIMENTAL - UNDER DEVELOPMENT - USE WITH CAUTION|
This plugin defines the {{{<<animate>>}}} macro that can be used to peform simple animations of formatted tiddler content by saving/setting/reseting the values of CSS style attributes at specified times. The macro can also be used to smoothly animate CSS styles that use ''numeric values'', by automatically computing a series of incremental values, ranging from //start// to //stop//, for a specified //duration//, with optional "pause-and-reverse" //cycles// to create repeating animations or continuous loops.
!!!!!Examples
>Please see [[AnimationEffectsSampler]] for a live animation example...
!!!!!Usage
<<<
The macro syntax is:
{{{
<<animate type source style format start stop wait duration cycles pause>>
<<animate type source "set" style value wait>>
<<animate source "save" style wait>>
<<animate source "reset" style wait>>
<<animate source "add" classname wait>>
<<animate source "remove" classname wait>>
}}}
> //note: default values are shown in parentheses for //optional// parameters. To ensure the correct order and number of parameters in the macro, you should enter these default values as 'placeholders' when using non-default values for other parameters. Of course, if all the remaining values that follow a non-default parameter are default values, they do not need to be specified, and can be safely omitted.//
where:
* ''//type// (="span")''<br>is either ''div'' or ''span'', and forces the animation container to be a "DIV" or "SPAN" element (i.e., displayed on a separate line, or inline with other content), which can affect how the specified CSS style will be applied. When this param is omitted (which is the general use case), the animation container defaults to the same type as the original content. When using a parameter with "inline" content (see below), a span element is created by default.
* ''//source//''<br>specifies the source content to be animated, and can be one of:
**''"text to display"''<br>inline wiki-syntax content, entered directly as a //quoted// macro parameter. The {{{<<animate>>}}} macro automatically creates a container at the current location and renders the content into it before animating.
**''@~TiddlerName''<br>as above, but retrieves and renders wiki-syntax content from another tiddler.
**''=elementID''<br>indicates a specific DOM element, by assigned ID (e.g., "mainMenu", "displayArea", "sidebar", etc.). The macro will animate this content from it's original location.
**''='' (or ''=here'')<br>indicates the current containing DOM element (i.e, the one in which the {{{<<animate>>}}} macro is embedded. The animation will affect all content that //precedes the macro// within the current container.
* ''"set"'', ''"save"'', ''"reset"'', ''"add"'', ''"remove"''<br>are keywords to indicate how to process the rest of the macro parameters. If ''set'' is used, the remaining parameters are interpeted as //style//, //value//, and //wait//, respectively, and the macro assigns the value to the specified style at the indicated time. The ''save'' and ''reset'' keywords expect only //style// and //wait// parameters following the keyword, where ''save'' retains a copy of the current CSS style value so that you can later use ''reset'' to re-assign the original saved value back to the specified CSS style. The ''add'' and ''remove'' keywords expect and //classname// and //wait// value, and adds/removes the specified classname from the animated element. If no keyword (or ''morph'') is specified, the remaining macro parameters are used to calculate and apply multiple incremental CSS values for smooth animation processing (a.k.a., "morphing").
* ''//style// (="left")''<br>indicates the CSS attribute to be animated (e.g., "left", "marginTop", "width", "fontSize", etc.). Note: if you embed more than one {{{<<animate>>}}} macro in the same container (to simultaneously alter multiple CSS attributes), only the //''last''// animation effect will be applied. To combine several effects, you must precede the //style// parameter value with a "+" symbol for all uses of {{{<<animate>>}}} //except// for the first occurrence within that container, which must //NOT// have a "+" symbol).
* ''//format// (="%0%")''<br>provides a 'text template' for generating CSS attribute values during animation, by using "%0" as a substitution marker to be automatically replaced by the current animation value, combined with a CSS measurement type (e.g., px, em, %, in, cm). For example: "%0px" produces pixel-based values (e.g., "27px", "342.873px", etc.), while "%0%" generates percentage-based relative measurements, (e.g., "-100%", "42%", etc.), and "%0em" results in measurements that are relative to the current font size (em).
* ''//start// (=-100) and //stop// (=0)'' or ''//value// (="")''<br>define the initial and ending values for the CSS attribute being animated. Note that, except when using the alternative ''set'' keyword syntax, these values must be numeric, as they are used to //calculate// the incremental values for each 'tick' of the animation processing.
* ''//wait// (=0)''<br>indicates the number of milliseconds to wait before starting the animation sequence. All animation macros that are embedded in the same content begin simultaneously. The //wait// value allows you to use several effects in sequence, by defining the start of each effect so that it does not begin until the previous one has completed.
* ''//duration// (=2000)''<br>indicates the number of milliseconds during which to animate from the //start// value to the //stop// value.
* ''//cycles// (=1)'' and ''//pause// (=1000)''<br>indicates the number of "reverse-and-repeat" cycles to perform and the pause (in milliseconds) in between each part of the cycle. When cycles=1 (or zero, or is omitted entirely), animation progresses from //start// to //stop// just once. However, if cycles>1, then the animation can pause for a specified amount of time before swapping the //start// and //stop// values and continuing ''//in reverse//''. A value of cycles=2 performs the animation twice, completing a single loop from //start// to //stop// and then back to //start// again, while cycles=3 does 1.5 loops (ending with the //stop// value), and cycles=4 does 2 complete loops (ending with the //start// value), etc. To loop forever, specify a cycle value of "-1".
In addition to the {{{<<animate>>}}} macro, the plugin also defines the following macro for backward-compatibility with the now retired [[ZoomTextPlugin]]:
{{{
<<zoomText "text to display" wait start stop duration cycles pause>>
<<zoomText @TiddlerName wait start stop duration cycles pause>>
}}}
This permits rendering of existing tiddlers that already contain the {{{<<zoomText>>}}} macro without needing to update those tiddlers. However, use of this older syntax is deprecated in favor of the more robust and flexible {{{<<animate>>}}} syntax described above.
<<<
/%
|Name|AnimationEffectsSampler|
|Source|http://www.TiddlyTools.com/#AnimationEffectsSampler|
|Version|2.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|sample|
|Requires|AnimationEffectsPlugin, StyleSheetShortcuts, CloseOtherTiddlers, RefreshTiddler, ReplaceTiddlerTitle|
|Description|demonstrates techniques for animating wiki-formatted content|
SET SPEED MULTIPLIER (global variable) [0:00]
%/<<tiddler {{
window.sec=config.options.txtAnimationEffectsRate||1000; // global abbreviation/default multiplier
config.options.txtAnimationEffectsRate=window.sec; // user option value initialization
""; // return blank tiddlername so macro doesn't produce output
}}>>/%
HIDE TIDDLER ELEMENTS [0:00]
%/<html><style>
#tiddlerAnimationEffectsSampler .subtitle,
#tiddlerAnimationEffectsSampler .tagged
{ display:none !important; }
#tiddlerAnimationEffectsSampler .viewer {
background-image:none !important;
background-color:transparent;
border:0; margin:0; padding:0;
}
</style></html>/%
CLOSE OTHER TIDDLERS [0:00]
%/<<tiddler CloseOtherTiddlers>>/%
HIDE PAGE ELEMENTS BEFORE ANIMATION [0:00]
%/<<animate =mainMenu save display {{0*sec}}>>/%
%/<<animate =mainMenu set display none {{0*sec}}>>/%
%/<<animate =sidebar save display {{0*sec}}>>/%
%/<<animate =sidebar set display none {{0*sec}}>>/%
%/<<animate =storyMenu save display {{0*sec}}>>/%
%/<<animate =storyMenu set display none {{0*sec}}>>/%
%/<<animate =siteTitle save display {{0*sec}}>>/%
%/<<animate =siteTitle set display none {{0*sec}}>>/%
%/<<animate =siteSubtitle save display {{0*sec}}>>/%
%/<<animate =siteSubtitle set display none {{0*sec}}>>/%
%/<<animate =displayArea save marginLeft {{0*sec}}>>/%
%/<<animate =displayArea set marginLeft 0 {{0*sec}}>>/%
%/<<animate =displayArea save marginRight {{0*sec}}>>/%
%/<<animate =displayArea set marginRight 0 {{0*sec}}>>/%
%/<<animate =siteMenu save visibility {{0*sec}}>>/%
%/<<animate =siteMenu set visibility hidden {{0*sec}}>>/%
%/<<animate =breadCrumbs save visibility {{0*sec}}>>/%
%/<<animate =breadCrumbs set visibility hidden {{0*sec}}>>/%
CONTAINER FOR SHOWING TIDDLER VIEWER BACKGROUND AT END OF ANIMATION
%/{{block{/%
LEFT/RIGHT SLIDING TEXT EFFECT [0:00 - 0:10]
%/@@position:absolute;width:100%;{{nowrap italic{/%
%/<<animate div "{{red{Are you}}}"
left %0% 0 50 {{0*sec}} {{1.5*sec}} 7>>/%
%/<<animate div "{{blue{getting dizzy?}}}"
left %0% 50 0 {{0*sec}} {{1.5*sec}} 7>>/%
%/<<animate = fontSize %0% 0 400 {{0*sec}} {{2.5*sec}} 4>>/%
%/<<animate = +marginTop %0% 0 10 {{0*sec}} {{1*sec}} 6>>/%
%/}}}@@/%
UP/DOWN SPINNING TEXT EFFECT [0:00 - 0:09]
%/{{big italic{
<<animate "{{floatleft right green{Are<br>you}}}"
fontSize %0% 0 300 {{0*sec}} {{1.5*sec}} 6>>/%
%/<<animate div "getting<br>dizzy?"
fontSize %0% 0 300 {{1.5*sec}} {{1.5*sec}} 6>>/%
%/<<animate = left %0% 20 35 {{0*sec}} {{1*sec}} 6>>/%
%/<<animate = +marginTop %0% 0 15 {{0*sec}} {{1*sec}} 6>>/%
%/<<animate = +right %0% 0 30 {{5*sec}} {{1*sec}} 6>>/%
%/}}}/%
ALMOST DONE MESSAGE [0:08 - 0:16.5]
%/{{big floatleft green{/%
%/''//almost done...//''/%
%/<<animate = set display none {{0*sec}}>>/%
%/<<animate = set display inline {{8*sec}}>>/%
%/<<animate = letterSpacing %0px 25 0 {{8*sec}} {{8*sec}}>>/%
%/<<animate = +fontSize %0% 100 0 {{16*sec}} {{.5*sec}}>>/%
%/}}}/%
SIDE-TO-SIDE "SWING" EFFECT (ALL TIDDLER CONTENT) [0:00 - 0:11.2]
%/<<animate = left %0% 45 0 {{0*sec}} {{1.6*sec}} 7>>/%
FINAL COUNTDOWN [0:11.5 - 0:16.5]
%/{{floatleft bold italic{/%
%/<<animate "5" fontSize %0% 0 400 {{11.5*sec}} {{.5*sec}} 2>>/%
%/<<animate "4" fontSize %0% 0 350 {{12.5*sec}} {{.5*sec}} 2>>/%
%/<<animate "3" fontSize %0% 0 300 {{13.5*sec}} {{.5*sec}} 2>>/%
%/<<animate "2" fontSize %0% 0 250 {{14.5*sec}} {{.5*sec}} 2>>/%
%/<<animate "1" fontSize %0% 0 200 {{15.5*sec}} {{.5*sec}} 2>>/%
%/}}}/%
RESTORE PAGE ELEMENTS AFTER PRIMARY ANIMATION [0:17]
%/<<animate =mainMenu reset display {{17*sec}}>>/%
%/<<animate =sidebar reset display {{17*sec}}>>/%
%/<<animate =storyMenu reset display {{17*sec}}>>/%
%/<<animate =siteTitle reset display {{17*sec}}>>/%
%/<<animate =siteSubtitle reset display {{17*sec}}>>/%
%/<<animate =displayArea reset marginLeft {{17*sec}}>>/%
%/<<animate =displayArea reset marginRight {{17*sec}}>>/%
%/<<animate =siteMenu reset visibility {{17*sec}}>>/%
%/<<animate =breadCrumbs reset visibility {{17*sec}}>>/%
SHOW CONTROL PANEL AND SOURCE DISPLAY [0:17 - 0:18.5] (END)
%/{{small{/%
%/<<animate = set display none {{0*sec}}>>/%
%/<<animate = set display inline {{17*sec}}>>/%
%/{{selected{{{toolbar{/%
%/{{fine{speed: }}}{{threechar smallform{<<option txtAnimationEffectsRate>>}}}/%
%/{{medium{<<tiddler RefreshTiddler with: "replay" "restart animation sequence">>}}}/%
%/<<animate = top %0px 200 0 {{17*sec}} {{1.5*sec}}>>/%
%/}}}}}}/%
%/{{block{/%
%/{{green{''animation sequence completed''}}}
//(see //[[AnimationEffectsPlugin]]// for macro definition/usage)// /%
%/<<animate = left %0% 100 0 {{17*sec}} {{1.5*sec}}>>/%
%/}}}/%
%/{{smallform stretch center clear{/%
%/<<tiddler AnimationEffectsSampler##showText
with: {{store.getValue('AnimationEffectsSampler','text').htmlEncode()}}>>/%
!showText
<html><nowiki><div class='editor'><textarea readonly rows='20'>$1</textarea></div></html>
!end
%/<<animate = left %0% -100 0 {{17*sec}} {{1.5*sec}}>>/%
%/}}}/%
%/}}}/%
SHOW TIDDLER TITLE [0:17 - 0:18.5] (END)
%/<<tiddler ReplaceTiddlerTitle with:
"~AnimationEffectsSampler\<\<animate div = left %0% -100 0 {{17*sec}\} {{1.5*sec}\}\>\>">>/%
SHOW VIEWER BACKGROUND [0:18]
%/<<animate = add viewer {{17.5*sec}}>>/%
%/}}}/% END OF CONTAINER FOR VIEWER BACKGROUND %/
/***
|Name|Blackout|
|Source|http://www.TiddlyTools.com/#Blackout|
|Version|1.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|CSS|
|Description|theme: black/blue-gray/gray backgrounds w/light text|
|StyleSheet|Blackout|
|PageTemplateReadOnly|PageTemplateReadOnly|
|EditTemplateReadOnly|EditTemplateReadOnly|
***/
[[StyleSheetAdjustments]]
[[BrightText]]
/* ==== blackout ==== */
/*{{{*/
body
{ background-color:#000; }
.menubox
{ background-color:#111; }
.viewer
{ background-color:#111; border: 1px solid #999; -moz-border-radius:1em;-webkit-border-radius:1em; padding:1em; }
.header
{ background-image: none; background-color:transparent; color:#ccf; border:0; }
.floatingPanel, .attachPanel, #importPanel, #exportPanel,
{ background: #eee; background-image: url('[[TexturesParchmentGray]]');}
.floatingPanel a, .attachPanel a, #messageArea a, #importPanel a, #exportPanel a, #sidebarTabs .tabContents a,
.floatingPanel .button, .attachPanel .button, #messageArea .button, #importPanel .button, #exportPanel .button, #sidebarTabs .tabContents .button,
.floatingPanel .tiddlyLinkExisting, .attachPanel .tiddlyLinkExisting, #messageArea .tiddlyLinkExisting, #importPanel .tiddlyLinkExisting, #exportPanel .tiddlyLinkExisting, #sidebarTabs .tabContents .tiddlyLinkExisting
{ color:#009; }
.siteMenu .floatingPanel, #messageArea
{ background: #eee; }
.tiddlyCard { background:#ffd; }
.viewer h1,.viewer h2,.viewer h3,.viewer h4,.viewer h5 { background: #666; color:#fff; }
.viewer .tabContents, #sidebarTabs .tabContents
{ background-color:#111; color:#fff; }
.tabContents a, .tabContents .button, .tabContents .tiddlyLinkExisting
{ color:#99f; }
/*}}}*/
/***
|Name|BrightText|
|Source|http://www.TiddlyTools.com/#BrightText|
|Version|1.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|CSS|
|Description|adjust font colors for use with dark backgrounds|
***/
/* background images */
/* colors and borders */
a, .button { color:#ccf; }
a:hover, .button:hover { color:#fff; }
#breadCrumbs { color:#ccc; }
#breadCrumbs a { color:#ccf; }
#titleLine { color: #fff; }
#titleLine a { color: #009900; }
.siteMenu { color: #fff; border:0; }
.siteMenu a, .siteMenu .button, .siteMenu .tiddlyLink { color: #ccf; }
.storyMenu { color: #fff; border:0; }
.storyMenu a, .storyMenu .button, .storyMenu .tiddlyLink { color: #ccf; }
/*
#mainMenu { color: #fff; }
#mainMenu .tiddlyLink { color: #def; }
#mainMenu .tiddlyLink:hover { color: #fff; }
#mainMenu .externalLink { color: #def; }
#mainMenu .externalLink:hover { color: #fff; }
#mainMenu .button, #mainMenu A { color: #def; }
#mainMenu .button:hover, #mainMenu A:hover { color: #fff; }
*/
#messageArea { color: #006; }
#messageArea a:link, #messageArea a:visited { color: #006; }
#messageArea a:hover { color: #f00; }
#messageArea a:active { color: #006; }
#popup { color: #000; }
#popup a { color: #006; }
#popup .viewer a { color: #ccf; }
#popup a:hover { color: #006; }
#popup .viewer a:hover { color: #fff; }
#popup hr { color: #666; }
.tabContents { color: #000; }
.tiddler .button { color: #ccf; }
.tiddler .button:hover { color: #fff; }
.tiddler .button:active { color: #fff; }
.title { color: #def; }
.subtitle { color: #89a; }
.toolbar { color: #aaa; }
.footer { color: #888; }
.selectedTiddler .footer { color: #ddd; }
.viewer { color: #fff; }
.viewer a:link, .viewer a:visited { color: #ccf; }
.viewer a:hover { color: #fff; }
.viewer .button { color: #def; }
.viewer .button:hover { color: #fff; }
.viewer th { color: #fff; }
.viewer td { color: #fff; }
.viewer code { color: #ccc; }
.viewer pre { color: #000; }
.viewer hr { color: #666; }
.viewer .highlight, .viewer .marked { color: #fff; }
.viewer .tabSelected { background-color: #002; color:#fff; border-color:#999; border-width:1px; padding-bottom:1px !important; }
.viewer .tabUnselected { background-color: transparent; color:#999; border-color:#666}
.viewer .tabContents { background-color: #002; color:#fff; border-color:#999; border-width:1px }
.tagging a, .tagged a, .tagging .button, .tagged .button { color: #009; }
.highlight, .marked { color: #fff; }
.lowlight a { color: #009 !important; }
.editor { color: #402C74; }
.editorFooter { color: #aaa; }
.editorFooter A { color: #930; }
.editorFooter A:hover { color: #cf6; }
.editorFooter A:active { color: #fff; }
#licensePanel A { color: #66f; }
#licensePanel A:hover { color: #fff; }
#licensePanel A:active { color: #fff; }
.errorNoSuchMacro { color: #ff0; }
.zoomer { color: #fff; }
.mouseover
{color:#336 !important;}
.mouseover a
{color:#336 !important;}
.selected .mouseover
{color:#ccf !important;}
.selected .mouseover .button, .selected .mouseover a
{color:#ccf !important;}
.selected .mouseover .moveablePanelButton
{color:#000 !important;}
.floatingPanel .button,
.floatingPanel a:link,
.floatingPanel a:hover,
.floatingPanel a:visited,
.selected .floatingPanel .button,
.selected .floatingPanel a:link,
.selected .floatingPanel a:hover,
.selected .floatingPanel a:visited,
.toolbar .floatingPanel .button,
.toolbar .floatingPanel a:link,
.toolbar .floatingPanel a:hover,
.toolbar .floatingPanel a:visited,
.viewer .floatingPanel .button,
.viewer .floatingPanel a:link,
.viewer .floatingPanel a:hover,
.viewer .floatingPanel a:visited {
color: #009 !important;
}
.floatingPanel .viewer .button,
.floatingPanel .viewer a:link,
.floatingPanel .viewer a:visited {
color: #ccf !important;
}
.floatingPanel a:hover,
.viewer .floatingPanel a:hover {
color: #fff !important;
}
/***
----
***/
/*{{{*/
.attachPanel a, #importPanel a, #exportpanel a,
.attachPanel .button, #importPanel .button, #exportpanel .button,
.attachPanel .tiddlyLinkExisting, #importPanel .tiddlyLinkExisting, #exportpanel .tiddlyLinkExisting,
.attachPanel .tiddlyLinkNonExisting, #importPanel .tiddlyLinkNonExisting, #exportpanel .tiddlyLinkNonExisting,
.tab .button, .tab A,
.tab .tiddlyLinkExisting, .tab .tiddlyLinkNonExisting
{ color:#009 !important; }
#sidebarOptions, #sidebarOptions .sliderPanel
{ color: #fff; }
#sidebarOptions .button, #sidebarOptions A,
#sidebarOptions .tiddlyLinkExisting, #sidebarOptions .tiddlyLinkNonExisting,
#sidebarOptions .sliderPanel .button, #sidebarOptions .sliderPanel A,
#sidebarOptions .sliderPanel .tiddlyLinkExisting, #sidebarOptions .sliderPanel .tiddlyLinkNonExisting
{ color: #def; }
#sidebarTabs, #sidebarTabs .sliderPanel, #sidebarTabs .tabContents
{ color: #fff; }
#sidebarTabs .tabContents *[class="TOCList"] /* MOZ ONLY */
{ color:#fff !important; }
#sidebarTabs .button, /* #sidebarTabs A, */
#sidebarTabs .tiddlyLinkExisting, #sidebarTabs .tiddlyLinkNonExisting
{ color: #def; }
.menubox
{ color:#fff; border-color:#999; }
.menubox .button, .menubox .tiddlyLinkExisting, .menubox .tiddlyLinkNonExisting
{ color:#99f !important; }
.QOTD
{ color:#fff !important; background:inherit !important; }
.groupbox, .groupbox table, .groupbox tbody, .groupbox tr, .groupbox td
{ color:#000; }
.groupbox a, .groupbox .button, .groupbox .tiddlyLinkExisting, .groupbox .tiddlyLinkNonExisting
{ color:#009 !important; }
.outline
{ border-color:#999; }
.floatingPanel, .floatingPanel table, .floatingPanel tbody, .floatingPanel tr, .floatingPanel td
{ color:#000; }
.toolbar {color:#336 !important;}
.toolbar a {color:#336 !important;}
.selected .toolbar { color:#999 !important; }
.selected .toolbar a {color:#ccf !important;}
.selected .toolbar a:hover {color:#fff !important; }
/*}}}*/
/***
|Name|CalendarPlugin|
|Source|http://www.TiddlyTools.com/#CalendarPlugin|
|Version|1.5.0|
|Author|Eric Shulman|
|Original Author|SteveRumsby|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Description|display monthly and yearly calendars|
NOTE: For //enhanced// date popup display, optionally install [[DatePlugin]] and [[ReminderMacros]]
!!!Usage:
<<<
|{{{<<calendar>>}}}|full-year calendar for the current year|
|{{{<<calendar year>>}}}|full-year calendar for the specified year|
|{{{<<calendar year month>>}}}|one month calendar for the specified month and year|
|{{{<<calendar thismonth>>}}}|one month calendar for the current month|
|{{{<<calendar lastmonth>>}}}|one month calendar for last month|
|{{{<<calendar nextmonth>>}}}|one month calendar for next month|
|{{{<<calendar +n>>}}}<br>{{{<<calendar -n>>}}}|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
<<<
2009.04.31 [1.5.0] rewrote onClickCalendarDate() (popup handler) and added config.options.txtCalendarReminderTags. Partial code reduction/cleanup. Assigned true version number (1.5.0)
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
***/
//{{{
version.extensions.CalendarPlugin= { major: 1, minor: 5, revision: 0, date: new Date(2009,5,31)};
//}}}
//{{{
if(config.options.txtCalFirstDay == undefined)
config.options.txtCalFirstDay = 0;
if(config.options.txtCalStartOfWeekend == undefined)
config.options.txtCalStartOfWeekend = 5;
if(config.options.chkDisplayWeekNumbers == undefined)
config.options.chkDisplayWeekNumbers = false;
if(config.options.chkDisplayWeekNumbers)
config.options.txtCalFirstDay = 0;
if(config.options.txtWeekNumberDisplayFormat == undefined)
config.options.txtWeekNumberDisplayFormat = 'w0WW';
if(config.options.txtWeekNumberLinkFormat == undefined)
config.options.txtWeekNumberLinkFormat = 'YYYY-w0WW';
if(config.options.txtCalendarReminderTags == undefined)
config.options.txtCalendarReminderTags = 'reminder';
config.macros.calendar = {
monthnames:['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
daynames:['M','T','W','T','F','S','S'],
todaybg:'#ccccff',
weekendbg:'#c0c0c0',
monthbg:'#e0e0e0',
holidaybg:'#ffc0c0',
journalDateFmt:'DD MMM YYYY',
monthdays:[31,28,31,30,31,30,31,31,30,31,30,31],
holidays:[ ] // for customization see [[CalendarPluginConfig]]
};
//}}}
//{{{
function calendarIsHoliday(date)
{
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');
var today = new Date();
var year = today.getYear();
if (year<1900) year+=1900;
// get journal format from SideBarOptions (ELS 5/29/06 - suggested by MartinBudden)
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;
}
//}}}
//{{{
// cache used to store reminders 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');
createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon]+' '+year, true, year, mon);
row = createTiddlyElement(calendar, 'tr');
createCalendarDayHeader(row, 1);
createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarMonth(calendar, year, mon)
{
var row = createTiddlyElement(calendar, 'tr');
createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon]+' '+ year, false, year, mon);
row = createTiddlyElement(calendar, 'tr');
createCalendarDayHeader(row, 1);
createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarYear(calendar, year)
{
var row;
row = createTiddlyElement(calendar, 'tr');
var back = createTiddlyElement(row, 'td');
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');
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');
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');
createCalendarDayHeader(row, 3);
createCalendarDayRows(cal, year, mon);
}
//}}}
//{{{
function createCalendarMonthHeader(cal, row, name, nav, year, mon)
{
var month;
if (nav) {
var back = createTiddlyElement(row, 'td');
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');
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');//wn**
}
for(i = 0; i < col; i++)
createTiddlyElement(row, 'td');
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');
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 10/30/05 - use <<date>> macro's showDate() function to create popup
// ELS 05/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++;
}
}
//}}}
//{{{
// Create a pop-up containing:
// * a link to a tiddler for this date
// * a 'new tiddler' link to add a reminder for this date
// * links to current reminders for this date
// NOTE: this code is only used if [[ReminderMacros]] is installed AND [[DatePlugin]] is //not// installed.
function onClickCalendarDate(ev) { ev=ev||window.event;
var d=new Date(this.getAttribute('title')); var date=d.formatString(config.macros.calendar.journalDateFmt);
var p=Popup.create(this); if (!p) return;
createTiddlyLink(createTiddlyElement(p,'li'),date,true);
var rem='\\n\\<\\<reminder day:%0 month:%1 year:%2 title: \\>\\>';
rem=rem.format([d.getDate(),d.getMonth()+1,d.getYear()+1900]);
var cmd="<<newTiddler label:[[new reminder...]] prompt:[[add a new reminder to '%0']]"
+" title:[[%0]] text:{{store.getTiddlerText('%0','')+'%1'}} tag:%2>>";
wikify(cmd.format([date,rem,config.options.txtCalendarReminderTags]),p);
createTiddlyElement(p,'hr');
var t=findTiddlersWithReminders(d,[0,31],null,1);
for(var i=0; i<t.length; i++) {
var link=createTiddlyLink(createTiddlyElement(p,'li'), t[i].tiddler, false);
link.appendChild(document.createTextNode(t[i]['params']['title']));
}
Popup.show(); ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); return false;
}
//}}}
//{{{
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');
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');
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');
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');
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";
//}}}
Contact Adam Warden directly and I will do my best to reply, typically within 24 hours.
Pricing is based on use, market, length of job and other considerations.
*Payment is accepted by Paypal.
* 3% handling fee to cover cost, paypal address below.
Feel free to contact me anytime via Email - Adam@StraightFocus.com
Or, you can call 847.489.2326 (ADAM) - if there is no answer please leave a message
Skype - therealjustadam
Thanks for taking the time!
/%
!info
|Name|CycleThemes|
|Source|http://www.TiddlyTools.com/#CycleThemes|
|Version|2.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|transclusion|
|Description|creates command link to cycle through systemThemes|
Usage
<<<
{{{
<<tiddler CycleThemes>>
<<tiddler CycleThemes with: label "theme theme theme">>
}}}
*''label'' (optional)<br>text of command link. default='next theme'
*''"theme theme theme"'' (optional)<br>list of theme tiddlers to cycle through. default=[[StyleSheet]] plus all tiddlers tagged with<<tag systemTheme>>, except those tagged with<<tag excludeTheme>>or<<tag excludeLists>>
<<<
Examples
<<<
*Cycle through all themes:<br>{{{<<tiddler CycleThemes>>}}}<br><<tiddler CycleThemes##show with: 'next theme' >>
*Toggle between two themes:<br>{{{<<tiddler CycleThemes with: "toggle" "StyleSheet Plain">>}}}<br><<tiddler CycleThemes##show with: "toggle" "StyleSheet Plain">>
*Apply a theme:<br>{{{<<tiddler CycleThemes with: "default" StyleSheet>>}}}<br><<tiddler CycleThemes##show with: "use default StyleSheet" StyleSheet>>
<<<
!end
!show
<html><nowiki><a href="javascript:;"
onmouseover="
this.title='current theme: '+config.options.txtTheme;
this.href='javascript:void(eval(decodeURIComponent(%22(function(){try{('
+encodeURIComponent(encodeURIComponent(this.onclick))
+')()}catch(e){alert(e.description?e.description:e.toString())}})()%22)))';"
onclick="
var titles='$2'.readBracketedList();
if ('$2'=='$'+'2') {
var tids=store.getTaggedTiddlers('systemTheme');
titles=tids.map(function(t){return t.tags.contains('excludeTheme','excludeLists')?null:t.title;});
titles.pushUnique('StyleSheet');
}
var curr=titles.indexOf(config.options.txtTheme);
var next=curr+1>=titles.length?0:curr+1;
while(!titles[next] && next!=curr) next=next+1>=titles.length?0:next+1;
story.switchTheme(titles[next]);
return false;"
>$1</a></html>
!end
%/<<tiddler {{var src='CycleThemes'; src+(tiddler&&tiddler.title==src?'##info':'##show')}}
with: {{'$1'=='$'+'1'?'next theme':'$1'}} "$2">>
/***
|Name|[[DatePlugin]]|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.7.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|formatted dates plus popup menu with 'journal' link, changes and (optional) reminders|
This plugin provides a general approach to displaying formatted dates and/or links and popups that permit easy navigation and management of tiddlers based on their creation/modification dates.
!!!!!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
<<<
2009.05.31 [2.7.1] in addRemindersToPopup(), 'new reminder....' command now uses {{{<<newTiddler>>}}} macro. Also, general code reduction/cleanup.
|please see [[DatePluginInfo]] for additional revision details|
2005.10.30 [0.9.0] pre-release
<<<
!!!!!Code
***/
//{{{
version.extensions.DatePlugin= {major: 2, minor: 7, revision: 1, date: new Date(2009,5,31)};
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'
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 ],
holidays: [ '01/01', '07/04', '07/24', '11/24' ]
// NewYearsDay, IndependenceDay(US), Eric's Birthday (hooray!), Thanksgiving(US)
};
config.macros.date.handler = function(place,macroName,params)
{
// default: display current date
var now =new Date();
var date=now;
var mode='display';
if (params[0]&&['display','popup','link'].contains(params[0].toLowerCase()))
{ mode=params[0]; params.shift(); }
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)
{
mode =mode||'display';
format =format||config.macros.date.format;
linkformat=linkformat||config.macros.date.linkformat;
// 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) { e=e||window.event;
var p=Popup.create(this); if (!p) return false;
// always show dated tiddler link (or just date, if readOnly) at the top...
if (!readOnly || store.tiddlerExists(this.date.formatString(this.linkformat)))
createTiddlyLink(createTiddlyElement(p,'li'),this.date.formatString(this.linkformat),true);
else
createTiddlyText(createTiddlyElement(p,'li'),this.date.formatString(this.linkformat));
if (!config.options.chkDatePopupHideCreated)
addCreatedsToPopup(p,this.date,this.format);
if (!config.options.chkDatePopupHideChanged)
addModifiedsToPopup(p,this.date,this.format);
if (!config.options.chkDatePopupHideTagged)
addTaggedToPopup(p,this.date,this.linkformat);
if (!config.options.chkDatePopupHideReminders)
addRemindersToPopup(p,this.date,this.linkformat);
Popup.show(); 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(p,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(p,'div',null,null,'created ('+createds.length+')');
for(var t=0; t<createds.length; t++) {
var link=createTiddlyLink(createTiddlyElement(p,'li'),createds[t],false);
link.appendChild(document.createTextNode(indent+createds[t]));
}
}
}
//}}}
//{{{
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(p,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(p,'div',null,null,'changed ('+mods.length+')');
for(var t=0; t<mods.length; t++) {
var link=createTiddlyLink(createTiddlyElement(p,'li'),mods[t],false);
link.appendChild(document.createTextNode(indent+mods[t]));
}
}
}
//}}}
//{{{
function hasTagged(date,format) // returns true if date is tagging other tiddlers
{
return store.getTaggedTiddlers(date.formatString(format)).length>0;
}
function addTaggedToPopup(p,when,format)
{
var indent=String.fromCharCode(160)+String.fromCharCode(160);
var tagged=store.getTaggedTiddlers(when.formatString(format));
if (tagged.length) var e=createTiddlyElement(p,'div',null,null,'tagged ('+tagged.length+')');
for(var t=0; t<tagged.length; t++) {
var link=createTiddlyLink(createTiddlyElement(p,'li'),tagged[t].title,false);
link.appendChild(document.createTextNode(indent+tagged[t].title));
}
}
//}}}
//{{{
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
var t = findTiddlersWithReminders(date, [0,leadtime], null, null, 1);
for(var i=0; i<t.length; i++) reminders[t[i].matchedDate]=true;
}
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(p,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(p,'div',null,null,'reminders ('+(reminders.length||'none')+')');
for(var t=0; t<reminders.length; t++) {
link = createTiddlyLink(createTiddlyElement(p,'li'),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));
}
if (readOnly) return; // readonly... omit 'new reminder...' command
var rem='\\<\\<reminder day:%0 month:%1 year:%2 title:"Enter a reminder title here"\\>\\>';
rem=rem.format([when.getDate(),when.getMonth()+1,when.getYear()+1900]);
var cmd="<<newTiddler label:[["+indent+"new reminder...]] prompt:[[add a reminder to '%0']]"
+" title:[[%0]] text:{{var t=store.getTiddlerText('%0','');t+(t.length?'\\n':'')+'%1'}} tag:%2>>";
wikify(cmd.format([when.formatString(format),rem,config.options.txtCalendarReminderTags||'']),
createTiddlyElement(p,'li'));
}
//}}}
/***
|Name|DatePluginConfig|
|Source|http://www.TiddlyTools.com/#DatePluginConfig|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.6.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|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);
}
var t=store.getTiddlerText(linkto,'')
if (config.options.chkInlineCalendarJournals && t.length) wikify('<br>'+t,place);
}
//}}}
|Name|DatePluginInfo|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.7.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for DatePlugin|
This plugin provides a general approach to displaying formatted dates and/or links and popups that permit easy navigation and management of tiddlers based on their creation/modification dates.
!!!!!Usage
<<<
This plugin displays formatted dates, for the specified year, month, day using number values or mathematical expressions such as (Y+1) or (D+30). Optionally, you can create a link to a 'dated tiddler' for quick blogging or create a popup menu that includes the dated tiddler link plus links to tiddlers that were created/changed on that date, or are tagged with that date and, if the RemindersPlugin is installed, any pending reminders for the coming 31 days. There is also a public API, so other plugins can embed a variety of formatted date output, links, and/or popup menus.
{{{
<<date mode date format linkformat>>
}}}
//all parameters are optional//
*''mode''<br>is one of:
**''display'' (default)<br>shows a formatted date
**''link''<br>creates a link to a specific 'date titled' tiddler
**''popup''<br>creates a popup command containing a dated tiddler link, plus links to changes and reminders.
*''date''<br>lets you enter ANY date (not just today) as ''year, month, and day values or simple mathematical expressions'' using pre-defined variables, Y, M, and D for the current year, month and day, repectively. You can display the modification date of the current tiddler by using the keyword: ''tiddler'' in place of the year, month and day parameters. Use ''tiddler://name-of-tiddler//'' to display the modification date of a specific tiddler. You can also use keywords ''today'' or ''filedate'' to refer to these //dynamically changing// date/time values.
*{{block{
''format'' and ''linkformat''
uses standard ~TiddlyWiki date formatting syntax. The default is "YYYY.0MM.0DD"
>''DDD'' - day of week in full (eg, "Monday"), ''DD'' - day of month, ''0DD'' - adds leading zero
>''MMM'' - month in full (eg, "July"), ''MM'' - month number, ''0MM'' - adds leading zero
>''YYYY'' - full year, ''YY'' - two digit year, ''hh'' - hours, ''mm'' - minutes, ''ss'' - seconds
>//note: use of hh, mm or ss format codes is only supported with ''tiddler'', ''today'' or ''filedate'' values//
}}}
*''linkformat''<br>specify an alternative date format so that the title of a 'dated tiddler' link can have a format that differs from the date's displayed format
In addition to the macro syntax, DatePlugin also provides a public javascript API so that other plugins that work with dates (such as calendar generators, etc.) can quickly incorporate date formatted links or popups into their output:
{{{
showDate(place, date, mode, format, linkformat, autostyle, weekend);
}}}
Note that the javascript API supports two //optional// true/false parameters, in addition those provided by the macro interface:
*''autostyle''<br>font/background styles of formatted dates are automatically adjusted to show the date's status: 'today' is boxed, 'changes' are bold, 'reminders' are underlined, weekends, holidays, changes, and reminders each have a different background color to make them more visibly distinct from one another.
*''weekend''<br>true=day is a weekend, false=day is a weekday, default=automatically determine if a given date falls on a weekend.
<<<
!!!!!Examples
<<<
The current date: <<date>>
The current time: <<date today "0hh:0mm:0ss">>
Today's blog: <<date link today "DDD, MMM DDth, YYYY">>
Recent blogs/changes/reminders: <<date popup Y M D-1 "yesterday">> <<date popup today "today">> <<date popup Y M D+1 "tomorrow">>
The first day of next month will be a <<date Y M+1 1 "DDD">>
This tiddler (DatePlugin) was last updated on: <<date tiddler "DDD, MMM DDth, YYYY">>
The SiteUrl was last updated on: <<date tiddler:SiteUrl "DDD, MMM DDth, YYYY">>
This document was last saved on <<date filedate "DDD, MMM DDth, YYYY at 0hh:0mm:0ss">>
<<date 2006 07 24 "MMM DDth, YYYY">> will be a <<date 2006 07 24 "DDD">>
<<<
!!!!!Revisions
<<<
2009.05.31 2.7.1 in addRemindersToPopup(), 'new reminder....' command now uses {{{<<newTiddler>>}}} macro. Also, general code reduction/cleanup.
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
2008.01.31 2.6.0 refactored date style logic into separate setDateStyle() function so it can be overridden by a custom definition. See [[DatePluginConfig]].
2008.01.11 2.5.0 added options to selectively suppress created/changes/tagged/reminders popup content
2008.01.08 [*.*.*] plugin size reduction: documentation moved to DatePluginInfo
2007.11.21 2.4.0 added hasTagged() and addTaggedToPopup() to list any tiddlers that has been tagged using the title of the dated journal tiddler asa tag value (i.e., the tiddlers that will be listed in the standard "tagging" display when viewing the journal tiddler itself). Based on a request from Coby.
2007.06.20 2.3.1 in onClickDatePopup(), use Popup.show() instead of deprecated ScrollToTiddlerPopup(). Fixes fatal error that prevents popups from being properly displayed
2007.05.31 2.3.0 list "created" tiddlers in date popup. Also, force re-cache of created/modified indices when displaying current date and store.isDirty(), so that popup is kept in sync with tiddler changes.
2006.05.09 2.2.1 added "todaybg" handling to set background color of current date. Also, honor excludeLists tag when getting lists of tiddlers. Based on suggestions by Mark Hulme.
2006.05.05 2.2.0 added "linkedbg" handling to set background color when a 'dated tiddler' exists. Based on a suggestion by Mark Hulme.
2006.03.08 2.1.2 add 'override leadtime' flag param in call to findTiddlersWithReminders(), and add "Enter a title" default text to new reminder handler. Thanks to Jeremy Sheeley for these additional tweaks.
2006.03.06 2.1.0 hasReminders() nows uses window.reminderCacheForCalendar[] when present. If calendar cache is not present, indexReminders() now uses findTiddlersWithReminders() with a 90-day look ahead to check for reminders. Also, switched default background colors for autostyled dates: reminders are now greenish ("c0ffee") and holidays are now reddish ("ffaace").
2006.02.14 2.0.5 when readOnly is set (by TW core), omit "new reminders..." popup menu item and, if a "dated tiddler" does not already exist, display the date as simple text instead of a link.
2006.02.05 2.0.4 added var to variables that were unintentionally global. Avoids FireFox 1.5.0.1 crash bug when referencing global variables
2006.01.18 2.0.3 In 1.2.x the tiddler editor's text area control was given an element ID=("tiddlerBody"+title), so that it was easy to locate this field and programmatically modify its content. With the addition of configuration templates in 2.x, the textarea no longer has an ID assigned. To find this control we now look through all the child nodes of the tiddler editor to locate a "textarea" control where attribute("edit") equals "text", and then append the new reminder to the contents of that control.
2006.01.11 2.0.2 correct 'weekend' override detection logic in showDate()
2006.01.10 2.0.1 allow custom-defined weekend days (default defined in config.macros.date.weekend[] array)
added flag param to showDate() API to override internal weekend[] array
2005.12.27 2.0.0 Update for TW2.0
Added parameter handling for 'linkformat'
2005.12.21 1.2.2 FF's date.getYear() function returns 105 (for the current year, 2005). When calculating a date value from Y M and D expressions, the plugin adds 1900 to the returned year value get the current year number. But IE's date.getYear() already returns 2005. As a result, plugin calculated date values on IE were incorrect (e.g., 3905 instead of 2005). Adding +1900 is now conditional so the values will be correct on both browsers.
2005.11.07 1.2.1 added support for "tiddler" dynamic date parameter
2005.11.06 1.2.0 added support for "tiddler:title" dynamic date parameter
2005.11.03 1.1.2 when a reminder doesn't have a specified title parameter, use the title of the tiddler that contains the reminder as "fallback" text in the popup menu. Based on a suggestion from BenjaminKudria.
2005.11.03 1.1.1 Temporarily bypass hasReminders() logic to avoid excessive overhead from generating the indexReminders() cache. While reminders can still appear in the popup menu, they just won't be indicated by auto-styling the date number that is displayed. This single change saves approx. 60% overhead (5 second delay reduced to under 2 seconds).
2005.11.01 1.1.0 corrected logic in hasModifieds() and hasReminders() so caching of indexed modifieds and reminders is done just once, as intended. This should hopefully speed up calendar generators and other plugins that render multiple dates...
2005.10.31 1.0.1 documentation and code cleanup
2005.10.31 1.0.0 initial public release
2005.10.30 0.9.0 pre-release
<<<
/***
|Name|DefaultTheme|
|Source|http://www.TiddlyTools.com/#DefaultTheme|
|Version|1.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|Description|Default systemTheme definition|
|StyleSheet|##StyleSheet|
|PageTemplate|##PageTemplate|
|ViewTemplate|##ViewTemplate|
|EditTemplate|##EditTemplate|
|PageTemplateReadOnly|##PageTemplateReadOnly|
|ViewTemplateReadOnly|##ViewTemplateReadOnly|
|EditTemplateReadOnly|##EditTemplateReadOnly|
!StyleSheet
/*{{{*/
[[StyleSheet]]
/*}}}*/
!PageTemplate
<!--{{{-->
[[PageTemplate]]
<!--}}}-->
!ViewTemplate
<!--{{{-->
[[ViewTemplate]]
<!--}}}-->
!EditTemplate
<!--{{{-->
[[EditTemplate]]
<!--}}}-->
!PageTemplateReadOnly
<!--{{{-->
[[PageTemplateReadOnly]]
<!--}}}-->
!ViewTemplateReadOnly
<!--{{{-->
[[ViewTemplate]]
<!--}}}-->
!EditTemplateReadOnly
<!--{{{-->
[[EditTemplateReadOnly]]
<!--}}}-->
***/
[[Home]]
[[What is it?]]
[[Get Yours]]
[[Contact]]
[[Calendar]]
/%
!info
|Name|DigitalClock|
|Source|http://www.TiddlyTools.com/#DigitalClock|
|Version|2.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|transclusion|
|Description|display current time with automatic update|
Usage
<<<
{{{
<<tiddler DigitalClock with: format tick>>
}}}
*''format'' is any TiddlyWiki date/time formatting string
*''tick'' is the time in seconds between display updates (default=1sec)
<<<
Example
<<<
show hours, minutes and seconds, updated once per second:
{{{<<tiddler DigitalClock with: "hh:0mm:0ss" 1>>}}}
<<tiddler DigitalClock##show with: "hh:0mm:0ss" 1>>
<<<
!end
!show
<html><a href='javascript:;'></a></html><<tiddler {{
window.DigitalClock_tick=function(id){
var e=document.getElementById(id); if (!e) return;
e.title='click to '+(e.paused?'RESUME':'PAUSE')+' clock display';
if (e.paused) return;
e.innerHTML=new Date().formatString(e.fmt);
e.timer=setTimeout('window.DigitalClock_tick('+id+')',e.tick*1000);
}
var e=place.lastChild.firstChild;
e.id=new Date().getTime()+Math.random();
e.onclick=function(){this.paused=!this.paused;window.DigitalClock_tick(this.id);}
e.style.cursor='pointer';
e.fmt=('$1'=='$'+'1')?'hh12:0mm:0ss am':'$1';
e.tick=('$2'=='$'+'2')?'1':'$2';
if (e.timer===undefined) window.DigitalClock_tick(e.id);
'';}}>>
!end
%/<<tiddler {{'DigitalClock##'+(tiddler&&tiddler.title=='DigitalClock'?'info':'show');}}
with: [[$1]] [[$2]]>>
/***
|Name|Edge of Night|
|Source|http://www.TiddlyTools.com/#Edge of Night|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|CSS|
|Description|theme: dark blue sunset photo background|
|StyleSheet|Edge of Night|
|PageTemplateReadOnly|PageTemplateReadOnly|
|EditTemplateReadOnly|EditTemplateReadOnly|
***/
[[StyleSheetAdjustments]]
[[BrightText]]
/* ==== Edge of Night ==== */
/*{{{*/
body
{ background-image: url('[[Edge of Night Background]]'); background-color:#113; }
.groupbox
{ background-image: url('[[TexturesParchmentGray]]');}
.menubox
{ background-image: none; background-color: #002; border:1px solid; }
.viewer
{ background-image: url('[[TexturesMarbleBlack]]'); background-color:#111; border: 1px solid #999; -moz-border-radius:1em;-webkit-border-radius:1em; padding:1em; }
.header
{ background-image: none; background-color:transparent; color:#ccf; border-bottom:0px solid #036; }
.siteSubtitle
{ color:#0c0; }
.floatingPanel, .attachPanel, #importPanel, #exportPanel
{ background: #eee; background-image: url('[[TexturesParchmentGray]]');}
.floatingPanel a, .attachPanel a, #importPanel a, #exportPanel a,
.floatingPanel .button, .attachPanel .button, #importPanel .button, #exportPanel .button,
.floatingPanel .tiddlyLinkExisting, .attachPanel .tiddlyLinkExisting, #importPanel .tiddlyLinkExisting, #exportPanel .tiddlyLinkExisting,
{ color:#009; }
#messageArea
{ background: #ddf; }
.siteMenu .floatingPanel
{ background-image: url('[[TexturesParchmentGray]]'); }
.viewer h1,.viewer h2,.viewer h3,.viewer h4,.viewer h5 { background: #666; color:#fff; }
.tabContents
{ background-color:#ddf; color:#000; background-image: url('[[TexturesParchmentGray]]'); }
.viewer .tabContents, #sidebarTabs .tabContents
{ background-image:none; background-color:#002; color:#fff; }
.tabContents a, .tabContents .button, .tabContents .tiddlyLinkExisting
{ color:#99f; }
/*********
#tiddlerWelcome .viewer .tabContents
{ background-image: url('[[TexturesMarbleBlack]]'); }
#mainMenu .menubox
{ background-image: url('[[TexturesMarbleBlack]]'); }
**********/
/*}}}*/
!usage
{{{[img[Edge of Night Background]]}}}
[img[Edge of Night Background]]
!notes
© 1999 ELS Design Studios - do not copy without prior explicit permission
!type
image/jpg
!file
./images/sunset.jpg
!url
http://www.TiddlyTools.com/images/sunset.jpg
!data
Get YOURS today, or soon as you can!
If you need help with anything - please feel free to contact me anytime. Alternatively you can also utilize TiddlyWiki's online as they all have open source content, so if you see something you like, you can use it - not to mention there is many of them so the variety and functionality is only hindered by your creativity.
I have only been involved with the TiddlyWiki for a short time, but I have been involved in coding for over 10 years - and I have never seen anything like this. Everyone NEEDS one of these, its better than sliced bread!
Feel free to contact me for consultation, design or creation of your new PortaDoc.
/***
|Name|GotoPlugin|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Documentation|http://www.TiddlyTools.com/#GotoPluginInfo|
|Version|1.9.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|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 displayed, pressing //escape// clears the current input.
!!!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.05.22 [1.9.2] use reverseLookup() for IncludePlugin
|please see [[GotoPluginInfo]] for additional revision details|
2006.05.05 [0.0.0] started
<<<
!!!Code
***/
//{{{
version.extensions.GotoPlugin= {major: 1, minor: 9, revision: 2, date: new Date(2009,5,22)};
// 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 showlist =params.contains("showlist");
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(/%showlist%/g,showlist);
html=html.replace(/%display%/g,showlist?'block':'none');
html=html.replace(/%position%/g,showlist?'static':'absolute');
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]);
var span=createTiddlyElement(place,'span');
span.innerHTML=html; var form=span.getElementsByTagName("form")[0];
if (showlist) this.fillList(form.list,'',filter,search,0);
},
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"\
onfocus="this.select(); this.setAttribute(\'accesskey\',\'G\');"\
%keyevent%="return config.macros.gotoTiddler.inputEscKeyHandler(event,this,this.form.list,%search%,%showlist%);"\
onkeyup="return config.macros.gotoTiddler.inputKeyHandler(event,this,%quiet%,%search%,%showlist%);">\
<select name=list style="display:%display%;position:%position%;%liststyle%"\
onchange="if (!this.selectedIndex) this.selectedIndex=1;"\
onblur="this.style.display=%showlist%?\'block\':\'none\';"\
%keyevent%="return config.macros.gotoTiddler.selectKeyHandler(event,this,this.form.gotoTiddler,%showlist%);"\
onclick="return config.macros.gotoTiddler.processItem(this.value,this.form.gotoTiddler,this,%showlist%);">\
</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(list,val,filter) {
if (!list.cache || !list.cache.length || val.length<=config.options.txtIncrementalSearchMin) {
// starting new search, fetch and cache list of tiddlers/shadows/tags
list.cache=new Array();
if (filter.length) {
var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
var tiddlers=store.sortTiddlers(fn.apply(store,[filter]),'title');
} else
var tiddlers=store.reverseLookup('tags','excludeLists');
for(var t=0; t<tiddlers.length; t++) list.cache.push(tiddlers[t].title);
if (!filter.length) {
for (var t in config.shadowTiddlers) list.cache.pushUnique(t);
var tags=store.getTags();
for(var t=0; t<tags.length; t++) list.cache.pushUnique(tags[t][0]);
}
}
var found = [];
var match=val.toLowerCase();
for(var i=0; i<list.cache.length; i++)
if (list.cache[i].toLowerCase().indexOf(match)!=-1) found.push(list.cache[i]);
return found;
},
getItemSuffix:
function(t) {
if (store.tiddlerExists(t)) return ""; // tiddler
if (store.isShadowTiddler(t)) return " (shadow)"; // shadow
return " (tag)"; // tag
},
fillList:
function(list,val,filter,search,key) {
if (list.style.display=="none") return; // not visible... do nothing!
var indent='\xa0\xa0\xa0';
var found = this.getItems(list,val,filter); // 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([val]),"*",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;
},
keyProcessed:
function(ev) { // utility function
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,search,showlist) {
if (event.keyCode==27) {
if (showlist) { // clear input, reset list
here.value=here.defaultValue;
this.fillList(list,'',here.form.filter.value,search,0);
}
else if (list.style.display=="none") // clear input
here.value=here.defaultValue;
else list.style.display="none"; // hide list
return this.keyProcessed(event);
}
return true; // key bubbles up
},
inputKeyHandler:
function(event,here,quiet,search,showlist) {
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 or reset list
if (!here.value.length && !(key==40 || key==13)) {
if (showlist) this.fillList(here.form.list,'',here.form.filter.value,search,0);
else list.style.display="none";
return this.keyProcessed(event);
}
// hide list if quiet, or below input minimum (and not showlist)
list.style.display=(!showlist&&(quiet||here.value.length<config.options.txtIncrementalSearchMin))?'none':'block';
// non-blank input... enter=show/create tiddler, SHIFT-enter=search for text
if (key==13 && here.value.length) return this.processItem(event.shiftKey?'*':here.value,here,list,showlist);
// up or down key, or enter with blank input... shows and moves to list...
if (key==38 || key==40 || key==13) { list.style.display="block"; list.focus(); }
this.fillList(list,here.value,filter.value,search,key);
return true; // key bubbles up
},
selectKeyHandler:
function(event,list,editfield,showlist) {
if (event.keyCode==27) // escape... hide list, move to edit field
{ editfield.focus(); list.style.display=showlist?'block':'none'; return this.keyProcessed(event); }
if (event.keyCode==13 && list.value.length) // enter... view selected item
{ this.processItem(list.value,editfield,list,showlist); return this.keyProcessed(event); }
return true; // key bubbles up
},
processItem:
function(title,here,list,showlist) {
if (!title.length) return;
list.style.display=showlist?'block':'none';
if (title=="*") { story.search(here.value); return false; } // do full-text search
if (!showlist) here.value=title;
story.displayTiddler(null,title); // show selected tiddler
return false;
}
}
//}}}
/***
|Name|GotoPluginInfo|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Documentation|http://www.TiddlyTools.com/#GotoPluginInfo|
|Version|1.9.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|Documentation for GotoPlugin|
''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 displayed, pressing //escape// clears the current input.
!!!!!Usage/Examples
<<<
syntax: {{{<<gotoTiddler quiet search inputstyle:... liststyle:... filter:...>>}}}
All parameters are optional.
* ''quiet'' (//keyword//)<br>list will not be automatically display as each character is typed. Use //down// or //enter// to view the list.
* ''showlist'' (//keyword//)<br>list will always be displayed, inline, directly below the input field.
* ''search'' (//keyword//)<br>adds an extra 'command item' to the list that can be used to invoke a full-text search using the entered value. This can be especially useful when no matching tiddler titles have been found.
* ''inputstyle:'' and ''liststyle:''<br>are CSS declarations that modify the default input and listbox styles, respectively. Note: the CSS styles must be surrounded by ({{{"..."}}} or {{{'...'}}}) or ({{{[[...]]}}}) (e.g., {{{liststyle:"border:1px dotted blue;color:green;..."}}}.
* ''filter:''<br>is a single tag value (or a boolean tag expression if MatchTagsPlugin is installed), and is used to limit the search to only those tiddlers matching the indicated tag or tag expression (e.g., {{{<<gotoTiddler filter:"faq or help">>}}})
{{{<<gotoTiddler>>}}}
<<gotoTiddler>>
{{{<<gotoTiddler search>>}}}
<<gotoTiddler search>>
{{{<<gotoTiddler showlist filter:"pluginInfo" liststyle:"height:10em;width:auto;">>}}}
<<gotoTiddler showlist filter:"pluginInfo" liststyle:"height:10em;width:auto;">>
<<<
!!!!!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.05.22 1.9.2 use reverseLookup() for IncludePlugin
2009.04.12 1.9.1 support multiple instances with different filters by using per-element tiddler cache instead of shared static cache
2009.04.05 1.9.0 added 'showlist' parameter for inline display with listbox always visible.
2009.03.23 1.8.0 added txtIncrementalSearchMin (default=3). Avoids fetching long lists. Use down arrow to force search with short input.
2008.12.15 1.7.1 up arrow from input field now moves to end of droplist (search for input). Also, shift+enter cam now be used to quickly invoke search for text.
2008.10.16 1.7.0 in macro handler(), changed to use //named// params instead of positional params, and added optional "filter:" param for tag filtering. Removed 'insert' handling (now provided by [[QuickEditPlugin]]).
2008.10.02 1.6.1 for IE, wrap controls in a table. Corrects placement of listbox so it is below input field.
2008.10.02 1.6.0 added 'search' param for optional "Search for:" item that invokes full text search (especially useful when no title matches are found)
2008.02.17 1.5.0 ENTER key always displays tiddler based on current input regardless of whether input matches any existing tiddler
2007.10.31 1.4.3 removed extra trailing comma on last property of config.macros.gotoTiddler object. This fixes an error under InternetExplorer that was introduced 6 days ago... sure, I should have found it sooner, but... WHY DON'T PEOPLE TELL ME WHEN THINGS ARE BROKEN!!!!
2007.10.25 1.4.2 added onclick handler for input field, so that clicking in field hides the listbox.
2007.10.25 1.4.1 re-wrote getItems() to cache list of tiddlers/shadows/tags and use case-folded simple text match instead of regular expression to find matching tiddlers. This *vastly* reduces processing overhead between keystrokes, especially for documents with many (>1000) tiddlers. Also, removed local definition of replaceSelection(), now supported directly by the TW2.2+ core, as well as via backward-compatible plugin
2007.04.25 1.4.0 renamed macro from "goto" to "gotoTiddler". This was necessary to avoid a fatal syntax error in Opera (and other browsers) that require strict adherence to ECMAScript 1.5 standards which defines the identifier "goto" as "reserved for FUTURE USE"... *sigh*
2007.04.21 1.3.2 in html definition, removed DIV around droplist (see 1.2.6 below). It created more layout problems then it solved. :-(
2007.04.01 1.3.1 in processItem(), ensure that correct textarea field is found by checking for edit=="text" attribute
2007.03.30 1.3.0 tweak SideBarOptions shadow to automatically add {{{<<goto>>}}} when using default sidebar content
2007.03.30 1.2.6 in html definition, added DIV around droplist to fix IE problem where list appears next to input field instead of below it.
2007.03.28 1.2.5 in processItem(), set focus to text area before setting selection (needed for IE to get correct selection 'range')
2007.03.28 1.2.4 added prompt for 'pretty text' when inserting a link into tiddler content
2007.03.28 1.2.3 added local copy of core replaceSelection() and modified for different replace logic
2007.03.27 1.2.2 in processItem(), use story.getTiddlerField() to retrieve textarea control
2007.03.26 1.2.1 in html, use either 'onkeydown' (IE) or 'onkeypress' (Moz) event to process <esc> key sooner, to prevent <esc> from 'bubbling up' to the tiddler (which will close the current editor).
2007.03.26 1.2.0 added support for optional "insert" keyword param.
2006.05.10 1.1.2 when filling listbox, set selection to 'heading' item... auto-select first tiddler title when down/enter moves focus into listbox
2006.05.08 1.1.1 added accesskey ("G") to input field html (also set when field gets focus). Also, inputKeyHandler() skips non-printing/non-editing keys.
2006.05.08 1.1.0 added heading to listbox for better feedback (also avoids problems with 1-line droplist)
2006.05.07 1.0.0 list matches against tiddlers/shadows/tags. input field auto-completion... 1st enter=complete matching input (or show list)... 2nd enter=view tiddler. "quiet" param controls when listbox appears. handling for enter (13), escape(27), and down(40) keys. Change 'ondblclick' to 'onclick' to avoid unintended triggering of tiddler editor). Shadow titles inserted into list instead of appended to the end.
2006.05.05 0.0.0 started
<<<
Welcome
----
Hola
----
Hala
----
Shalom
----
Ni hao
----
Kumusta
----
'Allo
----
G'day
----
Bon giorno
----
Hi
----
Hej
----
Olá
----
Salut
----
Hello
----
Oi
----
Hoi
----
Aloha
----
Bonjour
----
Guten Tag
----
Namaste
----
Ciao
<script>setTimeout("story.closeAllTiddlers('HolidayGreetings')",1);</script>/%
%/<<tiddler MoveTiddlerToTop>>/%
%/<<tiddler HideTiddlerTags>>/%
%/<<tiddler HideTiddlerBackground>>/%
%/<<tiddler HideTiddlerSubtitle>>/%
%/{{selected{{{toolbar{
{{fine{<<tiddler SlideshowTimer with: Welcome 70>> }}}/%
%/<<tiddler RefreshTiddler with: "replay">>/%
%/<script label="stop">
story.closeTiddler("HolidayGreetings");
story.displayTiddler(null,"Welcome"); story.refreshTiddler("Welcome",null,true);
return false;
</script>/%
%/}}}}}}/%
%/<html><hide linebreaks><embed src='midi/jingle_bells_jazz.mid'
width=100 height=16 autostart='true' autoplay='true'>
</embed></html>
@@position:absolute;width:50%;margin-left:20%;margin-top:-50px;white-space:nowrap;opacity:0.7;filter:'alpha(opacity:70)';///%
MULTI-HOLIDAY GREETINGS [0:02-0:35.5]
%/<<animate div "{{left red{Merry Christmas}}}" fontSize %0% 0 300 2000 1500 16 1500>>/%
%/<<animate div "{{right blue{Happy Hanukkah}}}" fontSize %0% 0 300 4000 1500 16 1500>>/%
%/<<animate div "{{center green{Eid Mubarak}}}" fontSize %0% 0 300 6000 1500 16 1500>>/%
%/<<animate div "{{right red{Happy Kwanzaa}}}" fontSize %0% 0 300 8000 1500 16 1500>>/%
%/<<animate div "{{center blue{Ponggalo Ponggal!}}}" fontSize %0% 0 300 10000 1500 16 1500>>/%
%/<<animate div "{{left green{Happy Solstice}}}" fontSize %0% 0 300 12000 1500 16 1500>>/%
%/<<animate div "{{center red{Happy Lohri}}}" fontSize %0% 0 300 14000 1500 16 1500>>/%
%/<<animate div "{{right blue{Festivus for the Rest Of Us!}}}" fontSize %0% 0 200 16000 1500 16 1500>>/%
%/<<animate div "{{left green{Happy Bodhi Day}}}" fontSize %0% 0 300 18000 1500 16 1500>>/%
%/<<animate div "{{right red{Merry Xmas}}}" fontSize %0% 0 300 20000 1500 16 1500>>/%
%/<<animate div "{{center blue{and a Happy New Year!}}}" fontSize %0% 0 200 22000 1500 16 1500>>/%
%/<<animate = left %0% 20 -20 0 2000 35>><<animate = +top %0px 0 100 0 1000 40>>/%
%///@@/%
BANNER MESSAGE "ROLLTEXT" [0:05-0:40], SCROLL OUT/HIDE [0:45-0:60]
%/{{block{
----
{{medium center{@@font-family:Trebuchet MS;//[>img[images/eric3.gif]]<script>
// see [[RollText]] script for general purpose utility...
var txt="Whatever you may be celebrating this time of year, be it the birth of a savior, or the strength of your forebears, the turning of the seasons, or nothing in particular... May the closing of your year be filled with the warmth of those around you and the joy of the season; may the year ahead be full of good fortune, hope, and wonder. May we all come together in the true spirit of the season to forget our differences and be grateful for everyone around us, give to those less fortunate, and celebrate the many things that all of us have worth celebrating in our lives.<br><br> {{floatleft{ {{fine{@@color:#999;//text by Alex Stewart//@@}}}}}} {{floatright{Love! }}} {{floatright{Laugh, }}} {{floatright{Live, }}} //{{right{<br>{{normal{...be well, be happy...}}}<br>-e}}}//";
var out='';
var words=txt.split(' ');
var when=5000;
for (var w=0; w<words.length; w++, when+=300)
out+='<<animate "'+words[w]+' " fontSize %0% 0 100 '+when+' 600>>';
return out;
</script>//@@}}}/%
%//% OFF <<animate = marginTop %0% 0 -250 45000 15000>> %//%
%//% OFF <<animate = +right %0% 0 -250 45000 15000>> %//%
%//% OFF <<animate = set display none 59500>> %//%
%/}}}
PortaDoc is the newest thing in portable document sharing. It is completely capable and ready to use out of the box with no advertising. It should be mentioned that it is also FREE to use as you wish. Although I may charge for programming and set up, as well as consultation and design, the actual TiddlyWiki is FREE!
Creative Custom Solutions offered through http://www.straightfocus.com
TiddlyWiki is a single html file which has all the characteristics of a [[wiki|WikiWikiWeb]] - including all of the content, the functionality (including editing, saving, tagging and searching) and the style sheet. Because it's a single file, it's very portable - you can email it, put it on a web server or share it via a [[USB stick|WikiOnAStick]].
Random Quote Time!
<<QOTD Quotations 10000>>
''But it's not just a wiki!'' It has very powerful plugin capabilities, so it can also be used to build new tools. You have full control over how it looks and behaves. For example, ~TiddlyWiki is already being used as:
*A personal notebook
*A GTD ("Getting Things Done") productivity tool
*A collaboration tool
*For building websites (this site is a ~TiddlyWiki file!)
*For rapid prototyping
*...and much more available from http://www.tiddlytools.com
You can import and export data to and from all sorts of places. Check out some of the [[Examples]] of ~TiddlyWiki in use, and the [[Features of TS]] that are available.
You can see the web functionality of ~TiddlyWiki by clicking on some of the links on this website. Double click some of the text to see 'edit mode'. For the full range of functions, including editing and saving changes, download and install a copy of the basic version and then follow the guidelines in [[Getting Started|GettingStarted]]. Have fun!
You can see the web functionality of TiddlyWiki by clicking on some of the links on this website. Double click some of the text to see 'edit mode'. For the full range of functions, including editing and saving changes, download and install a copy of the basic version and then follow the guidelines in Getting Started. Have fun!
Please visit the original http://TiddlyStix.tiddlyspot.com for all this on a memory stick!
Solutions created by http://AdamRock.TiddlySpot.com
This document was last saved on <<date filedate "DDD, MMM DDth, YYYY at 0hh:0mm:0ss">>
This package defines a set of small icons appear adjacent to the title of each tiddler and indicate various information about the tiddler, such as whether it has unsaved changes, or has been changed recently, or has been tagged as<<tag Trash>>. Additional icons indicate important categories of tiddlers (based on tags), such as plugins, scripts, templates, attachments, bookmarks, tasks, etc.
----
<<tiddler ShowAllIcons>>
----
{{fine italic{
Note: this package includes icons that are part of the "Silk" icon set: http://www.famfamfam.com/lab/icons/silk/ containing 1000 16-by-16 pixel icons in PNG format, created by Mark James, a part-time web developer, part-time student currently living in Birmingham, UK, and is licensed under a Creative Commons Attribution 2.5 License. Please visit http://www.famfamfam.com/ for further information and licensing details.}}}
/***
|Name|ImportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.6.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|interactive controls for import/export with filtering.|
Combine tiddlers from any two TiddlyWiki documents. Interactively select and copy tiddlers from another TiddlyWiki source document. Includes prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles. When done, a list of all imported tiddlers is written into [[ImportedTiddlers]].
!!!!!Documentation
<<<
see [[ImportTiddlersPluginInfo]] for details
<<<
!!!!!interactive control panel
<<<
<<importTiddlers inline>>
{{clear{
^^(see also: [[ImportTiddlers]] shadow tiddler)^^}}}
<<<
!!!!!Revisions
<<<
2009.10.10 4.6.1 in createImportPanel, Use {{{window.Components}}} instead of {{{config.browser.isGecko}}} to avoid applying FF3 'file browse' fixup in Chrome.
2009.10.06 4.6.0 added createTiddlerFromFile (import text files)
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 1.0.0 Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImportTiddlersPlugin= {major: 4, minor: 6, revision: 1, date: new Date(2009,10,10)};
// IE needs explicit global scoping for functions/vars called from browser events
window.onClickImportButton=onClickImportButton;
window.refreshImportList=refreshImportList;
// default cookie/option values
if (!config.options.chkImportReport) config.options.chkImportReport=true;
// default shadow definition
config.shadowTiddlers.ImportTiddlers='<<importTiddlers inline>>';
// use shadow tiddler content in backstage panel
if (config.tasks) config.tasks.importTask.content='<<tiddler ImportTiddlers>>' // TW2.2 or above
//}}}
//{{{
// backward-compatiblity for TW2.0.x and TW1.2.x
if (config.macros.importTiddlers==undefined) config.macros.importTiddlers={};
if (typeof merge=='undefined') {
function merge(dst,src,preserveExisting) {
for(var i in src) { if(!preserveExisting || dst[i] === undefined) dst[i] = src[i]; }
return dst;
}
}
if (config.browser.isGecko===undefined)
config.browser.isGecko=(config.userAgent.indexOf('gecko')!=-1);
//}}}
//{{{
merge(config.macros.importTiddlers,{
$: function(id) { return document.getElementById(id); }, // abbreviation
label: 'import tiddlers',
prompt: 'Copy tiddlers from another document',
openMsg: 'Opening %0',
openErrMsg: 'Could not open %0 - error=%1',
readMsg: 'Read %0 bytes from %1',
foundMsg: 'Found %0 tiddlers in %1',
filterMsg: "Filtered %0 tiddlers matching '%1'",
summaryMsg: '%0 tiddler%1 in the list',
summaryFilteredMsg: '%0 of %1 tiddler%2 in the list',
plural: 's are',
single: ' is',
countMsg: '%0 tiddlers selected for import',
processedMsg: 'Processed %0 tiddlers',
importedMsg: 'Imported %0 of %1 tiddlers from %2',
loadText: 'please load a document...',
closeText: 'close',
doneText: 'done',
startText: 'import',
stopText: 'stop',
local: true, // default to import from local file
src: '', // path/filename or URL of document to import (retrieved from SiteUrl)
proxy: '', // URL for remote proxy script (retrieved from SiteProxy)
useProxy: false, // use specific proxy script in front of remote URL
inbound: null, // hash-indexed array of tiddlers from other document
newTags: '', // text of tags added to imported tiddlers
addTags: true, // add new tags to imported tiddlers
listsize: 10, // # of lines to show in imported tiddler list
importTags: true, // include tags from remote source document when importing a tiddler
keepTags: true, // retain existing tags when replacing a tiddler
sync: false, // add 'server' fields to imported tiddlers (for sync function)
lastFilter: '', // most recent filter (URL hash) applied
lastAction: null, // most recent collision button performed
index: 0, // current processing index in import list
sort: '' // sort order for imported tiddler listbox
});
//}}}
//{{{
// hijack core macro handler
if (config.macros.importTiddlers.coreHandler==undefined)
config.macros.importTiddlers.coreHandler=config.macros.importTiddlers.handler;
config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
if (!params[0] || params[0].toLowerCase()=='core') { // default to built in
if (config.macros.importTiddlers.coreHandler)
config.macros.importTiddlers.coreHandler.apply(this,arguments);
else
createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);
} else if (params[0]=='link') { // show link to floating panel
createTiddlyButton(place,params[1]||this.label,params[2]||this.prompt,onClickImportMenu);
} else if (params[0]=='inline') {// show panel as INLINE tiddler content
createImportPanel(place);
this.$('importPanel').style.position='static';
this.$('importPanel').style.display='block';
} else if (config.macros.loadTiddlers)
config.macros.loadTiddlers.handler(place,macroName,params); // any other params: loadtiddlers
}
//}}}
//{{{
// Handle link click to create/show/hide control panel
function onClickImportMenu(e) { var e=e||window.event;
var parent=resolveTarget(e).parentNode;
var panel=document.getElementById('importPanel');
if (panel==undefined || panel.parentNode!=parent) panel=createImportPanel(parent);
var isOpen=panel.style.display=='block';
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,false,'none'));
else
panel.style.display=isOpen?'none':'block';
e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); return(false);
}
//}}}
//{{{
// Create control panel: HTML, CSS
function createImportPanel(place) {
var cmi=config.macros.importTiddlers; // abbrev
var panel=cmi.$('importPanel');
if (panel) { panel.parentNode.removeChild(panel); }
setStylesheet(store.getTiddlerText('ImportTiddlersPlugin##css'),'importTiddlers');
panel=createTiddlyElement(place,'span','importPanel',null,null)
panel.innerHTML=store.getTiddlerText('ImportTiddlersPlugin##html');
refreshImportList();
if (!cmi.src.length) cmi.src=store.getTiddlerText('SiteUrl')||'';
cmi.$('importSourceURL').value=cmi.src;
if (!cmi.proxy.length) cmi.proxy=store.getTiddlerText('SiteProxy')||'SiteProxy';
cmi.$('importSiteProxy').value=cmi.proxy;
if (window.Components) { // FF3 FIXUP
cmi.$('fileImportSource').style.display='none';
cmi.$('importLocalPanelFix').style.display='block';
}
cmi.$('chkSync').checked=cmi.sync;
cmi.$('chkImportTags').checked=cmi.importTags;
cmi.$('chkKeepTags').checked=cmi.keepTags;
cmi.$('chkAddTags').checked=cmi.addTags;
cmi.$('txtNewTags').value=cmi.newTags;
cmi.$('txtNewTags').style.display=cmi.addTags?'block':'none';
cmi.$('chkSync').checked=cmi.sync;
cmi.$('chkImportReport').checked=config.options.chkImportReport;
return panel;
}
//}}}
//{{{
// process control interactions
function onClickImportButton(which,event) {
var cmi=config.macros.importTiddlers; // abbreviation
var list=cmi.$('importList'); if (!list) return false;
var thePanel=cmi.$('importPanel');
var theCollisionPanel=cmi.$('importCollisionPanel');
var theNewTitle=cmi.$('importNewTitle');
var count=0;
switch (which.id)
{
case 'importFromFile': // show local panel
case 'importFromWeb': // show HTTP panel
cmi.local=(which.id=='importFromFile');
cmi.showPanel('importLocalPanel',cmi.local);
cmi.showPanel('importHTTPPanel',!cmi.local);
break;
case 'importOptions': // show/hide options panel
cmi.showPanel('importOptionsPanel',cmi.$('importOptionsPanel').style.display=='none');
break;
case 'fileImportSource':
case 'importLoad': // load import source into hidden frame
importReport(); // if an import was in progress, generate a report
cmi.inbound=null; // clear the imported tiddler buffer
refreshImportList(); // reset/resize the listbox
if (cmi.src=='') break;
// Load document, read it's DOM and fill the list
cmi.loadRemoteFile(cmi.src,cmi.filterTiddlerList);
break;
case 'importSelectFeed': // select a pre-defined systemServer feed URL
var p=Popup.create(which); if (!p) return false;
var tids=store.getTaggedTiddlers('systemServer');
if (!tids.length)
createTiddlyText(createTiddlyElement(p,'li'),'no pre-defined server feeds');
for (var t=0; t<tids.length; t++) {
var u=store.getTiddlerSlice(tids[t].title,'URL');
var d=store.getTiddlerSlice(tids[t].title,'Description');
if (!d||!d.length) d=store.getTiddlerSlice(tids[t].title,'description');
if (!d||!d.length) d=u;
createTiddlyButton(createTiddlyElement(p,'li'),tids[t].title,d,
function(){
var u=this.getAttribute('url');
document.getElementById('importSourceURL').value=u;
config.macros.importTiddlers.src=u;
document.getElementById('importLoad').onclick();
},
null,null,null,{url:u});
}
Popup.show();
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return false;
// create popup with feed list
// onselect, insert feed URL into input field.
break;
case 'importSelectAll': // select all tiddler list items (i.e., not headings)
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
if (list.options[t].value=='') continue;
list.options[t].selected=true;
count++;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
cmi.$('importStart').disabled=!count;
break;
case 'importSelectNew': // select tiddlers not in current document
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
list.options[t].selected=false;
if (list.options[t].value=='') continue;
list.options[t].selected=!store.tiddlerExists(list.options[t].value);
count+=list.options[t].selected?1:0;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
cmi.$('importStart').disabled=!count;
break;
case 'importSelectChanges': // select tiddlers that are updated from existing tiddlers
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
list.options[t].selected=false;
if (list.options[t].value==''||!store.tiddlerExists(list.options[t].value)) continue;
for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified>0); // updated tiddler
count+=list.options[t].selected?1:0;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
cmi.$('importStart').disabled=!count;
break;
case 'importSelectDifferences': // select tiddlers that are new or different from existing tiddlers
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
list.options[t].selected=false;
if (list.options[t].value=='') continue;
if (!store.tiddlerExists(list.options[t].value)) { list.options[t].selected=true; count++; continue; }
for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified!=0); // changed tiddler
count+=list.options[t].selected?1:0;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
cmi.$('importStart').disabled=!count;
break;
case 'importApplyFilter': // filter list to include only matching tiddlers
importReport(); // if an import was in progress, generate a report
clearMessage();
if (!cmi.all) // no tiddlers loaded = '0 selected'
{ displayMessage(cmi.countMsg.format([0])); return false; }
var hash=cmi.$('importLastFilter').value;
cmi.inbound=cmi.filterByHash('#'+hash,cmi.all);
refreshImportList(); // reset/resize the listbox
break;
case 'importStart': // initiate the import processing
importReport(); // if an import was in progress, generate a report
cmi.$('importApplyToAll').checked=false;
cmi.$('importStart').value=cmi.stopText;
if (cmi.index>0) cmi.index=-1; // stop processing
else cmi.index=importTiddlers(0); // or begin processing
importStopped();
break;
case 'importClose': // unload imported tiddlers or hide the import control panel
// if imported tiddlers not loaded, close the import control panel
if (!cmi.inbound) { thePanel.style.display='none'; break; }
importReport(); // if an import was in progress, generate a report
cmi.inbound=null; // clear the imported tiddler buffer
refreshImportList(); // reset/resize the listbox
break;
case 'importSkip': // don't import the tiddler
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
theImported.status='skipped after asking'; // mark item as skipped
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index+1); // resume with NEXT item
importStopped();
break;
case 'importRename': // change name of imported tiddler
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
theImported.status = 'renamed from '+theImported.title; // mark item as renamed
theImported.set(theNewTitle.value,null,null,null,null); // change the tiddler title
theItem.value = theNewTitle.value; // change the listbox item text
theItem.text = theNewTitle.value; // change the listbox item text
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index); // resume with THIS item
importStopped();
break;
case 'importMerge': // join existing and imported tiddler content
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
var theExisting = store.getTiddler(theItem.value);
var theText = theExisting.text+'\n----\n^^merged from: ';
theText +='[['+cmi.src+'#'+theItem.value+'|'+cmi.src+'#'+theItem.value+']]^^\n';
theText +='^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\n'+theImported.text;
var theDate = new Date();
var theTags = theExisting.getTags()+' '+theImported.getTags();
theImported.set(null,theText,null,theDate,theTags);
theImported.status = 'merged with '+theExisting.title; // mark item as merged
theImported.status += ' - '+theExisting.modified.formatString('MM/DD/YYYY 0hh:0mm:0ss');
theImported.status += ' by '+theExisting.modifier;
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index); // resume with this item
importStopped();
break;
case 'importReplace': // substitute imported tiddler for existing tiddler
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
var theExisting = store.getTiddler(theItem.value);
theImported.status = 'replaces '+theExisting.title; // mark item for replace
theImported.status += ' - '+theExisting.modified.formatString('MM/DD/YYYY 0hh:0mm:0ss');
theImported.status += ' by '+theExisting.modifier;
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index); // resume with THIS item
importStopped();
break;
case 'importListSmaller': // decrease current listbox size, minimum=5
if (list.options.length==1) break;
list.size-=(list.size>5)?1:0;
cmi.listsize=list.size;
break;
case 'importListLarger': // increase current listbox size, maximum=number of items in list
if (list.options.length==1) break;
list.size+=(list.size<list.options.length)?1:0;
cmi.listsize=list.size;
break;
case 'importListMaximize': // toggle listbox size between current and maximum
if (list.options.length==1) break;
list.size=(list.size==list.options.length)?cmi.listsize:list.options.length;
break;
}
}
//}}}
//{{{
config.macros.importTiddlers.showPanel=function(place,show,skipAnim) {
if (typeof place=='string') var place=document.getElementById(place);
if (!place||!place.style) return;
if(!skipAnim && anim && config.options.chkAnimate) anim.startAnimating(new Slider(place,show,false,'none'));
else place.style.display=show?'block':'none';
}
//}}}
//{{{
function refreshImportList(selectedIndex) {
var cmi=config.macros.importTiddlers; // abbrev
var list=cmi.$('importList'); if (!list) return;
// if nothing to show, reset list content and size
if (!cmi.inbound) {
while (list.length > 0) { list.options[0] = null; }
list.options[0]=new Option(cmi.loadText,'',false,false);
list.size=cmi.listsize;
cmi.$('importLoad').disabled=false;
cmi.$('importLoad').style.display='inline';
cmi.$('importStart').disabled=true;
cmi.$('importOptions').disabled=true;
cmi.$('importOptions').style.display='none';
cmi.$('fileImportSource').disabled=false;
cmi.$('importFromFile').disabled=false;
cmi.$('importFromWeb').disabled=false;
cmi.$('importStart').value=cmi.startText;
cmi.$('importClose').value=cmi.doneText;
cmi.$('importSelectPanel').style.display='none';
cmi.$('importOptionsPanel').style.display='none';
return;
}
// there are inbound tiddlers loaded...
cmi.$('importLoad').disabled=true;
cmi.$('importLoad').style.display='none';
cmi.$('importOptions').style.display='inline';
cmi.$('importOptions').disabled=false;
cmi.$('fileImportSource').disabled=true;
cmi.$('importFromFile').disabled=true;
cmi.$('importFromWeb').disabled=true;
cmi.$('importClose').value=cmi.closeText;
if (cmi.$('importSelectPanel').style.display=='none')
cmi.showPanel('importSelectPanel',true);
// get the sort order
if (!selectedIndex) selectedIndex=0;
if (selectedIndex==0) cmi.sort='title'; // heading
if (selectedIndex==1) cmi.sort='title';
if (selectedIndex==2) cmi.sort='modified';
if (selectedIndex==3) cmi.sort='tags';
if (selectedIndex>3) {
// display selected tiddler count
for (var t=0,count=0; t < list.options.length; t++) {
if (!list.options[t].selected) continue;
if (list.options[t].value!='')
count+=1;
else { // if heading is selected, deselect it, and then select and count all in section
list.options[t].selected=false;
for ( t++; t<list.options.length && list.options[t].value!=''; t++) {
list.options[t].selected=true;
count++;
}
}
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
}
cmi.$('importStart').disabled=!count;
if (selectedIndex>3) return; // no refresh needed
// get the alphasorted list of tiddlers
var tiddlers=cmi.inbound;
tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
// clear current list contents
while (list.length > 0) { list.options[0] = null; }
// add heading and control items to list
var i=0;
var indent=String.fromCharCode(160)+String.fromCharCode(160);
if (cmi.all.length==tiddlers.length)
var summary=cmi.summaryMsg.format([tiddlers.length,(tiddlers.length!=1)?cmi.plural:cmi.single]);
else
var summary=cmi.summaryFilteredMsg.format([tiddlers.length,cmi.all.length,(cmi.all.length!=1)?cmi.plural:cmi.single]);
list.options[i++]=new Option(summary,'',false,false);
list.options[i++]=new Option(((cmi.sort=='title' )?'>':indent)+' [by title]','',false,false);
list.options[i++]=new Option(((cmi.sort=='modified')?'>':indent)+' [by date]','',false,false);
list.options[i++]=new Option(((cmi.sort=='tags')?'>':indent)+' [by tags]','',false,false);
// output the tiddler list
switch(cmi.sort) {
case 'title':
for(var t = 0; t < tiddlers.length; t++)
list.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
break;
case 'modified':
// sort descending for newest date first
tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });
var lastSection = '';
for(var t = 0; t < tiddlers.length; t++) {
var tiddler = tiddlers[t];
var theSection = tiddler.modified.toLocaleDateString();
if (theSection != lastSection) {
list.options[i++] = new Option(theSection,'',false,false);
lastSection = theSection;
}
list.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
}
break;
case 'tags':
var theTitles = {}; // all tiddler titles, hash indexed by tag value
var theTags = new Array();
for(var t=0; t<tiddlers.length; t++) {
var title=tiddlers[t].title;
var tags=tiddlers[t].tags;
if (!tags || !tags.length) {
if (theTitles['untagged']==undefined) { theTags.push('untagged'); theTitles['untagged']=new Array(); }
theTitles['untagged'].push(title);
}
else for(var s=0; s<tags.length; s++) {
if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
theTitles[tags[s]].push(title);
}
}
theTags.sort();
for(var tagindex=0; tagindex<theTags.length; tagindex++) {
var theTag=theTags[tagindex];
list.options[i++]=new Option(theTag,'',false,false);
for(var t=0; t<theTitles[theTag].length; t++)
list.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
}
break;
}
list.selectedIndex=selectedIndex; // select current control item
if (list.size<cmi.listsize) list.size=cmi.listsize;
if (list.size>list.options.length) list.size=list.options.length;
}
//}}}
//{{{
// re-entrant processing for handling import with interactive collision prompting
function importTiddlers(startIndex) {
var cmi=config.macros.importTiddlers; // abbrev
if (!cmi.inbound) return -1;
var list=cmi.$('importList'); if (!list) return;
var t;
// if starting new import, reset import status flags
if (startIndex==0)
for (var t=0;t<cmi.inbound.length;t++)
cmi.inbound[t].status='';
for (var i=startIndex; i<list.options.length; i++) {
// if list item is not selected or is a heading (i.e., has no value), skip it
if ((!list.options[i].selected) || ((t=list.options[i].value)==''))
continue;
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==t) break;
var inbound = cmi.inbound[j];
var theExisting = store.getTiddler(inbound.title);
// avoid redundant import for tiddlers that are listed multiple times (when 'by tags')
if (inbound.status=='added')
continue;
// don't import the 'ImportedTiddlers' history from the other document...
if (inbound.title=='ImportedTiddlers')
continue;
// if tiddler exists and import not marked for replace or merge, stop importing
if (theExisting && (inbound.status.substr(0,7)!='replace') && (inbound.status.substr(0,5)!='merge'))
return i;
// assemble tags (remote + existing + added)
var newTags = '';
if (cmi.importTags)
newTags+=inbound.getTags() // import remote tags
if (cmi.keepTags && theExisting)
newTags+=' '+theExisting.getTags(); // keep existing tags
if (cmi.addTags && cmi.newTags.trim().length)
newTags+=' '+cmi.newTags; // add new tags
inbound.set(null,null,null,null,newTags.trim());
// set the status to 'added' (if not already set by the 'ask the user' UI)
inbound.status=(inbound.status=='')?'added':inbound.status;
// set sync fields
if (cmi.sync) {
if (!inbound.fields) inbound.fields={}; // for TW2.1.x backward-compatibility
inbound.fields['server.page.revision']=inbound.modified.convertToYYYYMMDDHHMM();
inbound.fields['server.type']='file';
inbound.fields['server.host']=(cmi.local&&!cmi.src.startsWith('file:')?'file:///':'')+cmi.src;
}
// do the import!
store.suspendNotifications();
store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier, inbound.modified, inbound.tags, inbound.fields, true, inbound.created);
store.fetchTiddler(inbound.title).created = inbound.created; // force creation date to imported value (needed for TW2.1.x and earlier)
store.resumeNotifications();
}
return(-1); // signals that we really finished the entire list
}
function importStopped() {
var cmi=config.macros.importTiddlers; // abbrev
var list=cmi.$('importList'); if (!list) return;
var theNewTitle=cmi.$('importNewTitle');
if (cmi.index==-1){
cmi.$('importStart').value=cmi.startText;
importReport(); // import finished... generate the report
} else {
// import collision...
// show the collision panel and set the title edit field
cmi.$('importStart').value=cmi.stopText;
cmi.showPanel('importCollisionPanel',true);
theNewTitle.value=list.options[cmi.index].value;
if (cmi.$('importApplyToAll').checked && cmi.lastAction && cmi.lastAction.id!='importRename')
onClickImportButton(cmi.lastAction);
}
}
//}}}
//{{{
function importReport() {
var cmi=config.macros.importTiddlers; // abbrev
if (!cmi.inbound) return;
// if import was not completed, the collision panel will still be open... close it now.
var panel=cmi.$('importCollisionPanel'); if (panel) panel.style.display='none';
// get the alphasorted list of tiddlers
var tiddlers = cmi.inbound;
// gather the statistics
var count=0; var total=0;
for (var t=0; t<tiddlers.length; t++) {
if (!tiddlers[t].status || !tiddlers[t].status.trim().length) continue;
if (tiddlers[t].status.substr(0,7)!='skipped') count++;
total++;
}
// generate a report
if (total) displayMessage(cmi.processedMsg.format([total]));
if (count && config.options.chkImportReport) {
// get/create the report tiddler
var theReport = store.getTiddler('ImportedTiddlers');
if (!theReport) { theReport=new Tiddler(); theReport.title='ImportedTiddlers'; theReport.text=''; }
// format the report content
var now = new Date();
var newText = 'On '+now.toLocaleString()+', '+config.options.txtUserName
newText +=' imported '+count+' tiddler'+(count==1?'':'s')+' from\n[['+cmi.src+'|'+cmi.src+']]:\n';
if (cmi.addTags && cmi.newTags.trim().length)
newText += 'imported tiddlers were tagged with: "'+cmi.newTags+'"\n';
newText += '<<<\n';
for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status)
newText += '#[['+tiddlers[t].title+']] - '+tiddlers[t].status+'\n';
newText += '<<<\n';
// update the ImportedTiddlers content and show the tiddler
theReport.text = newText+((theReport.text!='')?'\n----\n':'')+theReport.text;
theReport.modifier = config.options.txtUserName;
theReport.modified = new Date();
store.saveTiddler(theReport.title, theReport.title, theReport.text, theReport.modifier, theReport.modified, theReport.tags, theReport.fields);
story.displayTiddler(null,theReport.title,1,null,null,false);
story.refreshTiddler(theReport.title,1,true);
}
// reset status flags
for (var t=0; t<cmi.inbound.length; t++) cmi.inbound[t].status='';
// mark document as dirty and let display update as needed
if (count) { store.setDirty(true); store.notifyAll(); }
// always show final message when tiddlers were actually loaded
if (count) displayMessage(cmi.importedMsg.format([count,tiddlers.length,cmi.src.replace(/%20/g,' ')]));
}
//}}}
//{{{
// // File and XMLHttpRequest I/O
config.macros.importTiddlers.askForFilename=function(here) {
var msg=here.title; // use tooltip as dialog box message
var path=getLocalPath(document.location.href);
var slashpos=path.lastIndexOf('/'); if (slashpos==-1) slashpos=path.lastIndexOf('\\');
if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
var file='';
var result='';
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='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 { // XPSP2 IE 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) { // fallback
var result=prompt(msg,path+file);
}
}
return result;
}
config.macros.importTiddlers.loadRemoteFile = function(src,callback) {
if (src==undefined || !src.length) return null; // filename is required
var original=src; // URL as specified
var hashpos=src.indexOf('#'); if (hashpos!=-1) src=src.substr(0,hashpos); // URL with #... suffix removed (needed for IE)
clearMessage();
displayMessage(this.openMsg.format([src.replace(/%20/g,' ')]));
if (src.substr(0,5)!='http:' && src.substr(0,5)!='file:') { // if not a URL, read from local filesystem
var txt=loadFile(src);
if (!txt) { // file didn't load, might be relative path.. try fixup
var pathPrefix=document.location.href; // get current document path and trim off filename
var slashpos=pathPrefix.lastIndexOf('/'); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf('\\');
if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
src=pathPrefix+src;
if (pathPrefix.substr(0,5)!='http:') src=getLocalPath(src);
var txt=loadFile(src);
}
if (!txt) { // file still didn't load, report error
displayMessage(config.macros.importTiddlers.openErrMsg.format([src.replace(/%20/g,' '),'(filesystem error)']));
} else {
displayMessage(config.macros.importTiddlers.readMsg.format([txt.length,src.replace(/%20/g,' ')]));
if (version.major+version.minor*.1+version.revision*.01!=2.52) txt=convertUTF8ToUnicode(txt);
if (callback) callback(true,original,txt,src,null);
}
} else {
doHttp('GET',src,null,null,config.options.txtRemoteUsername,config.options.txtRemotePassword,callback,original,null);
}
}
config.macros.importTiddlers.readTiddlersFromHTML=function(html){
var remoteStore=new TiddlyWiki();
remoteStore.importTiddlyWiki(html);
return remoteStore.getTiddlers('title');
}
config.macros.importTiddlers.readTiddlersFromCSV=function(CSV){
var remoteStore=new TiddlyWiki();
// GET NAMES
var lines=CSV.replace(/\r/g,'').split('\n');
var names=lines.shift().replace(/"/g,'').split(',');
CSV=lines.join('\n');
// ENCODE commas and newlines within quoted values
var comma='!~comma~!'; var commaRE=new RegExp(comma,'g');
var newline='!~newline~!'; var newlineRE=new RegExp(newline,'g');
CSV=CSV.replace(/"([^"]*?)"/g,
function(x){ return x.replace(/\,/g,comma).replace(/\n/g,newline); });
// PARSE lines
var lines=CSV.split('\n');
for (var i=0; i<lines.length; i++) { if (!lines[i].length) continue;
var values=lines[i].split(',');
// DECODE commas, newlines, and doubled-quotes, and remove enclosing quotes (if any)
for (var v=0; v<values.length; v++)
values[v]=values[v].replace(commaRE,',').replace(newlineRE,'\n')
.replace(/^"|"$/g,'').replace(/""/g,'"');
// EXTRACT tiddler values
var title=''; var text=''; var tags=[]; var fields={};
var created=null; var when=new Date(); var who=config.options.txtUserName;
for (var v=0; v<values.length; v++) { var val=values[v];
if (names[v]) switch(names[v].toLowerCase()) {
case 'title': title=val.replace(/\[\]\|/g,'_'); break;
case 'created': created=new Date(val); break;
case 'modified':when=new Date(val); break;
case 'modifier':who=val; break;
case 'text': text=val; break;
case 'tags': tags=val.readBracketedList(); break;
default: fields[names[v].toLowerCase()]=val; break;
}
}
// CREATE tiddler in temporary store
if (title.length)
remoteStore.saveTiddler(title,title,text,who,when,tags,fields,true,created||when);
}
return remoteStore.getTiddlers('title');
}
config.macros.importTiddlers.createTiddlerFromFile=function(src,txt) {
var t=new Tiddler();
var pos=src.lastIndexOf("/"); if (pos==-1) pos=src.lastIndexOf("\\");
t.title=pos==-1?src:src.substr(pos+1);
t.text=txt;
t.created=t.modified=new Date();
t.modifier=config.options.txtUserName;
if (src.substr(src.length-3,3)=='.js') t.tags=['systemConfig'];
return [t];
}
config.macros.importTiddlers.filterTiddlerList=function(success,params,txt,src,xhr){
var cmi=config.macros.importTiddlers; // abbreviation
var src=src.replace(/%20/g,' ');
if (!success) { displayMessage(cmi.openErrMsg.format([src,xhr.status])); return; }
cmi.all=cmi.readTiddlersFromHTML(txt);
if (!cmi.all||!cmi.all.length) cmi.all=cmi.readTiddlersFromCSV(txt)
if (!cmi.all||!cmi.all.length) cmi.all=cmi.createTiddlerFromFile(src,txt)
var count=cmi.all?cmi.all.length:0;
var querypos=src.lastIndexOf('?'); if (querypos!=-1) src=src.substr(0,querypos);
displayMessage(cmi.foundMsg.format([count,src]));
cmi.inbound=cmi.filterByHash(params,cmi.all); // use full URL including hash (if any)
cmi.$('importLastFilter').value=cmi.lastFilter;
window.refreshImportList(0);
}
config.macros.importTiddlers.filterByHash=function(src,tiddlers){
var hashpos=src.lastIndexOf('#'); if (hashpos==-1) return tiddlers;
var hash=src.substr(hashpos+1); if (!hash.length) return tiddlers;
var tids=[];
var params=hash.parseParams('anon',null,true,false,false);
for (var p=1; p<params.length; p++) {
switch (params[p].name) {
case 'anon':
case 'open':
tids.pushUnique(params[p].value);
break;
case 'tag':
if (store.getMatchingTiddlers) { // for boolean expressions - see MatchTagsPlugin
var r=store.getMatchingTiddlers(params[p].value,null,tiddlers);
for (var t=0; t<r.length; t++) tids.pushUnique(r[t].title);
} else for (var t=0; t<tiddlers.length; t++)
if (tiddlers[t].isTagged(params[p].value))
tids.pushUnique(tiddlers[t].title);
break;
case 'story':
for (var t=0; t<tiddlers.length; t++)
if (tiddlers[t].title==params[p].value) {
tiddlers[t].changed();
for (var s=0; s<tiddlers[t].links.length; s++)
tids.pushUnique(tiddlers[t].links[s]);
break;
}
break;
case 'search':
for (var t=0; t<tiddlers.length; t++)
if (tiddlers[t].text.indexOf(params[p].value)!=-1)
tids.pushUnique(tiddlers[t].title);
break;
}
}
var matches=[];
for (var t=0; t<tiddlers.length; t++)
if (tids.contains(tiddlers[t].title))
matches.push(tiddlers[t]);
displayMessage(config.macros.importTiddlers.filterMsg.format([matches.length,hash]));
config.macros.importTiddlers.lastFilter=hash;
return matches;
}
//}}}
/***
!!!Control panel CSS
//{{{
!css
#importPanel {
display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;
background-color: #eee; color:#000; font-size: 8pt; line-height:110%;
border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;
padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em;
}
#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }
#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }
#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }
#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }
#importPanel select { width:100%;margin:0px;font-size:8pt;line-height:110%;}
#importPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}
#importPanel .box { border:1px solid #000; background-color:#eee; padding:3px 5px; margin-bottom:5px; -moz-border-radius:5px;-webkit-border-radius:5px;}
#importPanel .topline { border-top:1px solid #999; padding-top:2px; margin-top:2px; }
#importPanel .rad { width:auto; }
#importPanel .chk { width:auto; margin:1px;border:0; }
#importPanel .btn { width:auto; }
#importPanel .btn1 { width:98%; }
#importPanel .btn2 { width:48%; }
#importPanel .btn3 { width:32%; }
#importPanel .btn4 { width:23%; }
#importPanel .btn5 { width:19%; }
#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }
#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }
#backstagePanel #importPanel { left:10%; right:auto; }
!end
//}}}
!!!Control panel HTML
//{{{
!html
<!-- source and report -->
<table><tr><td align=left>
import from
<input type="radio" class="rad" name="importFrom" id="importFromFile" value="file" CHECKED
onclick="onClickImportButton(this,event)" title="show file controls"> local file
<input type="radio" class="rad" name="importFrom" id="importFromWeb" value="http"
onclick="onClickImportButton(this,event)" title="show web controls"> web server
</td><td align=right>
<input type=checkbox class="chk" id="chkImportReport"
onClick="config.options['chkImportReport']=this.checked;"> create report
</td></tr></table>
<div class="box" id="importSourcePanel" style="margin:.5em">
<div id="importLocalPanel" style="display:block;margin-bottom:2px;"><!-- import from local file -->
enter or browse for source path/filename<br>
<input type="file" id="fileImportSource" size=57 style="width:100%"
onKeyUp="config.macros.importTiddlers.src=this.value"
onChange="config.macros.importTiddlers.src=this.value;document.getElementById('importLoad').onclick()">
<div id="importLocalPanelFix" style="display:none"><!-- FF3 FIXUP -->
<input type="text" id="fileImportSourceFix" style="width:90%"
title="Enter a path/file to import"
onKeyUp="config.macros.importTiddlers.src=this.value"
onChange="config.macros.importTiddlers.src=this.value;document.getElementById('importLoad').onclick()">
<input type="button" id="fileImportSourceFixButton" style="width:7%" value="..."
title="Select a path/file to import"
onClick="var r=config.macros.importTiddlers.askForFilename(this); if (!r||!r.length) return;
document.getElementById('fileImportSourceFix').value=r;
config.macros.importTiddlers.src=r;
document.getElementById('importLoad').onclick()">
</div><!--end FF3 FIXUP-->
</div><!--end local-->
<div id="importHTTPPanel" style="display:none;margin-bottom:2px;"><!-- import from http server -->
<table><tr><td align=left>
enter a URL or <a href="javascript:;" id="importSelectFeed"
onclick="return onClickImportButton(this,event)" title="select a pre-defined 'systemServer' URL">
select a server</a><br>
</td><td align=right>
<input type="checkbox" class="chk" id="importUsePassword"
onClick="config.macros.importTiddlers.usePassword=this.checked;
config.macros.importTiddlers.showPanel('importIDPWPanel',this.checked,true);">password
<input type="checkbox" class="chk" id="importUseProxy"
onClick="config.macros.importTiddlers.useProxy=this.checked;
config.macros.importTiddlers.showPanel('importSiteProxy',this.checked,true);">proxy
</td></tr></table>
<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"
onKeyUp="config.macros.importTiddlers.proxy=this.value"
onChange="config.macros.importTiddlers.proxy=this.value;">
<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"
onKeyUp="config.macros.importTiddlers.src=this.value"
onChange="config.macros.importTiddlers.src=this.value;">
<div id="importIDPWPanel" style="text-align:center;margin-top:2px;display:none";>
username: <input type=text id="txtImportID" style="width:25%"
onChange="config.options.txtRemoteUsername=this.value;">
password: <input type=password id="txtImportPW" style="width:25%"
onChange="config.options.txtRemotePassword=this.value;">
</div><!--end idpw-->
</div><!--end http-->
</div><!--end source-->
<div class="box" id="importSelectPanel" style="display:none;margin:.5em;">
<table><tr><td align=left>
select:
<a href="javascript:;" id="importSelectAll"
onclick="return onClickImportButton(this)" title="SELECT all tiddlers">
all</a>
<a href="javascript:;" id="importSelectNew"
onclick="return onClickImportButton(this)" title="SELECT tiddlers not already in destination document">
added</a>
<a href="javascript:;" id="importSelectChanges"
onclick="return onClickImportButton(this)" title="SELECT tiddlers that have been updated in source document">
changes</a>
<a href="javascript:;" id="importSelectDifferences"
onclick="return onClickImportButton(this)" title="SELECT tiddlers that have been added or are different from existing tiddlers">
differences</a>
</td><td align=right>
<a href="javascript:;" id="importListSmaller"
onclick="return onClickImportButton(this)" title="SHRINK list size">
– </a>
<a href="javascript:;" id="importListLarger"
onclick="return onClickImportButton(this)" title="GROW list size">
+ </a>
<a href="javascript:;" id="importListMaximize"
onclick="return onClickImportButton(this)" title="MAXIMIZE/RESTORE list size">
= </a>
</td></tr></table>
<select id="importList" size=8 multiple
onchange="setTimeout('refreshImportList('+this.selectedIndex+')',1)">
<!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->
</select>
<div style="text-align:center">
<a href="javascript:;"
title="click for help using filters..."
onclick="alert('A filter consists of one or more space-separated combinations of: tiddlertitle, tag:[[tagvalue]], tag:[[tag expression]] (requires MatchTagsPlugin), story:[[TiddlerName]], and/or search:[[searchtext]]. Use a blank filter to restore the list of all tiddlers.'); return false;"
>filter</a>
<input type="text" id="importLastFilter" style="margin-bottom:1px; width:65%"
title="Enter a combination of one or more filters. Use a blank filter for all tiddlers."
onfocus="this.select()" value=""
onKeyUp="config.macros.importTiddlers.lastFilter=this.value"
onChange="config.macros.importTiddlers.lastFilter=this.value;">
<input type="button" id="importApplyFilter" style="width:20%" value="apply"
title="filter list of tiddlers to include only those that match certain criteria"
onclick="return onClickImportButton(this)">
</div>
</div><!--end select-->
<div class="box" id="importOptionsPanel" style="text-align:center;margin:.5em;display:none;">
apply tags: <input type=checkbox class="chk" id="chkImportTags" checked
onClick="config.macros.importTiddlers.importTags=this.checked;">from source
<input type=checkbox class="chk" id="chkKeepTags" checked
onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing
<input type=checkbox class="chk" id="chkAddTags"
onClick="config.macros.importTiddlers.addTags=this.checked;
config.macros.importTiddlers.showPanel('txtNewTags',this.checked,false);
if (this.checked) document.getElementById('txtNewTags').focus();">add tags<br>
<input type=text id="txtNewTags" style="margin-top:4px;display:none;" size=15 onfocus="this.select()"
title="enter tags to be added to imported tiddlers"
onKeyUp="config.macros.importTiddlers.newTags=this.value;
document.getElementById('chkAddTags').checked=this.value.length>0;" autocomplete=off>
<nobr><input type=checkbox class="chk" id="chkSync"
onClick="config.macros.importTiddlers.sync=this.checked;">
link tiddlers to source document (for sync later)</nobr>
</div><!--end options-->
<div id="importButtonPanel" style="text-align:center">
<input type=button id="importLoad" class="importButton btn3" value="open"
title="load listbox with tiddlers from source document"
onclick="onClickImportButton(this)">
<input type=button id="importOptions" class="importButton btn3" value="options..."
title="set options for tags, sync, etc."
onclick="onClickImportButton(this)">
<input type=button id="importStart" class="importButton btn3" value="import"
title="start/stop import of selected source tiddlers into current document"
onclick="onClickImportButton(this)">
<input type=button id="importClose" class="importButton btn3" value="done"
title="clear listbox or hide control panel"
onclick="onClickImportButton(this)">
</div>
<div class="none" id="importCollisionPanel" style="display:none;margin:.5em 0 .5em .5em;">
<table><tr><td style="width:65%" align="left">
<table><tr><td align=left>
tiddler already exists:
</td><td align=right>
<input type=checkbox class="chk" id="importApplyToAll"
onclick="document.getElementById('importRename').disabled=this.checked;"
checked>apply to all
</td></tr></table>
<input type=text id="importNewTitle" size=15 autocomplete=off">
</td><td style="width:34%" align="center">
<input type=button id="importMerge"
class="importButton" style="width:47%" value="merge"
title="append the incoming tiddler to the existing tiddler"
onclick="onClickImportButton(this)"><!--
--><input type=button id="importSkip"
class="importButton" style="width:47%" value="skip"
title="do not import this tiddler"
onclick="onClickImportButton(this)"><!--
--><br><input type=button id="importRename"
class="importButton" style="width:47%" value="rename"
title="rename the incoming tiddler"
onclick="onClickImportButton(this)"><!--
--><input type=button id="importReplace"
class="importButton" style="width:47%" value="replace"
title="discard the existing tiddler"
onclick="onClickImportButton(this)">
</td></tr></table>
</div><!--end collision-->
!end
//}}}
***/
/***
|Name|ImportTiddlersPluginInfo|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.6.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for ImportTiddlersPlugin|
Combine tiddlers from any two TiddlyWiki documents. An interactive control panel lets you pick a source document and import selected tiddlers, with prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles. Generates a detailed report of import 'history' in ImportedTiddlers.
!!!!!Usage
<<<
{{{<<importTiddlers>>}}} or {{{<<importTiddlers core>>}}}
invokes the built-in importTiddlers macro (TW2.1.x+). If installed in documents using TW2.0.x or earlier, fallback is to use 'link' display (see below)
{{{<<importTiddlers link label tooltip>>}}}
The ''link'' keyword creates an "import tiddlers" link that when clicked to show/hide import control panel. ''label'' and ''tooltip'' are optional text parameters (enclosed in quotes or {{{[[...]]}}}, and allow you to override the default display text for the link and the mouseover help text, respectively.
{{{<<importTiddlers inline>>}}}
creates import control panel directly in tiddler content
<<importTiddlers inline>>
Enter a document URL or press "..." to select a TiddlyWiki file to import, and then press ''[open]''. //Note: There may be a delay before the list of tiddlers appears.// Use the ''[-]'', ''[+]'', or ''[=]'' links to adjust the listbox size so you can view more (or less) tiddler titles at one time.
Select one or more titles from the listbox. Use CTRL-click or SHIFT-click to select/deselect individual titles. Click on ''all'', ''new'', ''changes'', or ''differences'' to automatically select a subset of tiddlers from the list, based on a comparison of the two documents:
*''all'' selects ALL tiddlers from the import source document, even if they have not been changed.
*''new'' selects only tiddlers that are found in the import source document, but do not yet exist in the destination document
*''changes'' selects only tiddlers that exist in both documents but that are newer in the source document
*''differences'' selects all new and existing tiddlers that are different from the destination document (even if destination tiddler is newer)
Press ''[import]'' to begin copying tiddlers to the current document. If an 'inbound' tiddler matches one that already exists in the document, the import process pauses and the tiddler title is displayed in an input field, along with four push buttons: ''skip'', ''rename'', ''merge'' and ''replace''.
* to bypass importing the tiddler, press ''skip''
* to give the inbound tiddler a different name, so that both the old and new tiddlers will exist when the import is done, enter a new title in the input field and press ''rename''
* to combine the content from both tiddlers into a single tiddler so you can then edit it later to eliminate unwanted content, press ''merge''
* to overwrite the existing tiddler with the imported one (discarding the previous content), press ''[replace]''
''Import Report History''
Whenever tiddlers are imported, a report is generated into a tiddler named [[ImportedTiddlers]], recording when the latest import was performed, the number of tiddlers successfully imported, from what location, and by whom, as well as a list of the tiddlers that were processed. When more tiddlers are imported at a later time, a new report is //added// to the existing [[ImportedTiddlers]], above the previous report (i.e., at the top of the tiddler), so that a history of imports is maintained. If this record is not desired, you can delete [[ImportedTiddlers]] at any time.
Note: You can prevent a report from being generated for any given import activity by clearing the "create a report" checkbox before pressing the ''import'' button
<<<
!!!!!Installation Notes
<<<
* As of 6/27/2007, support for TW2.1.x and earlier have been moved to [[ImportTiddlersPluginPatch]]. ''//Only install the patch plugin when using TW2.1.x or earlier.//''
<<<
!!!!!Revisions
<<<
2009.10.06 4.6.0 added createTiddlerFromFile (import text files)
2009.09.27 4.5.5 in readTiddlersFromCSV(), strip \r from input and fixed handling for quoted values
2009.09.12 4.5.4 fixed 'return false' to prevent IE page transition. Also, moved html/css definitions to separate sections
2009.08.23 4.5.3 in importTiddlers(), add 'file:///' to local server.host sync field only if not already present in URL
2009.08.20 4.5.2 only use SiteURL/SiteProxy values if control panel value has not yet been set
2009.07.03 4.5.1 fixups for TW252: doHttp() doesn't return XHR and convertUTF8ToUnicode() not needed for local I/O
2009.05.04 4.5.0 import from CSV-formatted files
2009.03.04 4.4.2 in createImportPanel(), init option checkboxes so display matches internal state variables
2009.02.26 4.4.1 use macro-specific definition of $() function abbreviation (avoids conflict with JQuery)
2008.09.30 4.4.0 added fallback definition of merge() for use with TW2.0.x and TW1.2.x
2008.08.12 4.3.3 rewrite backstage and shadow tiddler definitions for easier customization
2008.08.05 4.3.2 rewrote loadRemoteFile() to eliminate use of platform-specific fileExists() function
2008.06.29 4.3.1 More layout/animation work for simpler sequential interaction. Code reduction/cleanup
2008.06.28 4.3.0 HTML and CSS cleanup and tweaks to layout. Added animation to panels
2008.06.22 4.2.0 For FireFox, use HTML with separate text+button control instead of type='file' control
2008.06.05 4.1.0 in filterByHash(), added support for boolean tag expressions using getMatchingTiddlers() (defined by MatchTagsPlugin)
2008.05.12 4.0.2 automatically tweak the backstage "import" task to add the ImportTiddlers control panel
2008.04.30 4.0.1 trim #... suffix for loading files/URLs in IE
2008.04.30 4.0.0 added source filtering (using URL paramifiers). Also, abbreviations for code-size reduction.
2008.04.13 3.9.0 added 'apply to all' checkbox for collision processing
2008.03.26 3.8.0 added support for selecting pre-defined systemServer URLs
2008.03.25 3.7.0 added support for setting 'server' fields on imported tiddlers (for later synchronizing of changes)
2008.01.03 3.6.0 in loadRemoteFile(), use lower-level doHttp() instead of loadRemoteFile() in order to support username/password access to remote server
2007.10.30 3.5.6 update [[ImportTiddlers]] shadow tiddler definition to include "inline" link
2007.06.27 3.5.5 added missing 'fields' params to saveTiddler() calls. Fixes problem where importing tiddlers would lose the custom fields. Also, moved functions for TW2.1.x to [[ImportTiddlersPluginPatch2.1.x]].
2007.06.25 3.5.4 added calls to store.suspendNotifications() and store.resumeNotifications(). Eliminates redisplay processing overhead DURING import activities
2007.04.29 3.5.3 in refreshImportList() when inbound tiddlers are loaded, change "close" button to "done", and disable certain controls to creates a modal condition, so that actions that reload tiddlers cannot be performed unless "done" is first pressed to end the mode..
2007.04.28 3.5.2 in handler(), added param support for custom link label/prompt
2007.04.19 3.5.1 in readTiddlersFromHTML(), for TW2.2 and above, use importTiddlyWiki() (new core functionality) to get tiddlers from remote file content. Also, copied updated TW21Loader.prototype.internalizeTiddler() definition from TW2.2b5 so plugin can read tiddlers from TW2.2+ even when running under TW2.1.x
2007.03.22 3.5.0 in refreshImportList(), add handling for 'select section' when a heading is selected. Makes it really easy to import by tag or date!
2007.03.21 3.4.0 split loadTiddlers functionality into separate plugin (see [[LoadTiddlersPlugin]])
2007.03.20 3.3.1 tweak to previous change to allow relative file references via http: (bypasses getLocalPath() so remote URL will be used)
2007.03.20 3.3.0 added support for local, relative file references: in loadRemoteFile(), check for fileExists(). If not found, prepend relative path and retry.
2007.02.24 3.2.1 re-labeled control panel "open" button to "load"
2007.02.09 3.2.0 loadTiddlers: added support for "noReload" tag (prevents overwriting existing tiddler, even if inbound tiddler is newer)
2007.02.08 3.1.3 loadTiddlers: added missing code and documentation for "newTags" handling (a feature change from long, long ago that somehow got lost!)
2006.11.14 3.1.2 fix macro handler parameter declaration (double-pasted param list corrupts IE)
2006.11.13 3.1.1 use apply() method to invoke hijacked core handler
2006.11.13 3.1.0 hijack built-in importTiddlers.handler() to co-exist with plugin interface. If no params or 'core' keyword, display core interface. "link" param embeds "import tiddlers" link that shows floating panel when clicked.
2006.10.12 3.0.8 in readTiddlersFromHTML(), fallback to find end of store area by matching "/body" when POST-BODY-START is not present (backward compatibility for older documents)
2006.09.10 3.0.7 in readTiddlersFromHTML(), find end of store area by matching "POST-BODY-START" instead of "/body"
2006.08.16 3.0.6 Use higher-level store.saveTiddler() instead of store.addTiddler() to avoid conflicts with adaptations that hijack low-level tiddler handling. in CreateImportPanel(), removed "refresh listbox after every tiddler change".
2006.07.29 3.0.5 added noChangeMsg to loadTiddlers processing. if not 'quiet' mode, reports skipped tiddlers.
2006.04.18 3.0.4 in loadTiddlers.handler, fixed parsing of "prompt:" param. Also, corrected parameters mismatch in loadTiddlers() callback function definition (order of params was wrong, resulting in filters NOT being applied)
2006.04.12 3.0.3 moved many display messages to macro properties for easier L10N translations via 'lingo' definitions.
2006.04.12 3.0.2 more work on 'core candidate' code. Proposed API now defines "loadRemoteFile()" for XMLHttpRequest processing with built in fallback for handling local filesystem access, and readTiddlersFromHTML() to process the resulting source HTML content.
2006.04.04 3.0.1 in refreshImportList(), when using [by tags], tiddlers without tags are now included in a new "untagged" psuedo-tag list section
2006.04.04 3.0.0 Separate non-interactive {{{<<importTiddlers...>>}}} macro functionality for incorporation into TW2.1 core and renamed as {{{<<loadTiddlers>>}}} macro. New parameters for loadTiddlers: ''label:text'' and ''prompt:text'' for link creation, ''ask'' for filename/URL, ''tag:text'' for filtering, "confirm" for accept/reject of individual inbound tiddlers. Removed support for "importReplace/importPublic" tags and "force" param (unused feature).
2006.03.30 2.9.1 when extracting store area from remote URL, look for "</body>" instead of "</body>\n</html>" so it will match even if the "\n" is absent from the source.
2006.03.30 2.9.0 added optional 'force' macro param. When present, autoImportTiddlers() bypasses the checks for importPublic and importReplace. Based on a request from Tom Otvos.
2006.03.28 2.8.1 in loadImportFile(), added checks to see if 'netscape' and 'x.overrideMimeType()' are defined (not in IE). Also, when extracting store area, look for "</body>\n</html>" and omit extra content that may have been added to the end of the file.
2006.02.21 2.8.0 added support for "tiddler:TiddlerName" filtering parameter in auto-import processing
2006.02.21 2.7.1 Clean up layout problems with IE. (Use tables for alignment instead of SPANs styled with float:left and float:right)
2006.02.21 2.7.0 Added "local file" and "web server" radio buttons. Default remote URL uses value from [[SiteURL]]. Also, added 'proxy' option, using value from [[SiteProxy]] as prefix to permit cross-domain document access via server-side scripting.
2006.02.17 2.6.0 Removed "differences only" listbox display mode, replaced with selection filter 'presets': all/new/changes/differences. fixed init of "add new tags" checkbox
2006.02.16 2.5.4 added checkbox options to control "import remote tags" and "keep existing tags" behavior, in addition to existing "add new tags" functionality.
2006.02.14 2.5.3 FF1501 corrected unintended global 't' (loop index) in importReport() and autoImportTiddlers()
2006.02.10 2.5.2 corrected unintended global variable in importReport().
2006.02.05 2.5.1 moved globals from window.* to config.macros.importTiddlers.* to avoid FireFox 1.5.0.1 crash bug when referencing globals
2006.01.18 2.5.0 added checkbox for "create a report". Default is to create/update the ImportedTiddlers report.
2006.01.15 2.4.1 added "importPublic" tag and inverted default so that auto sharing is NOT done unless tagged with importPublic
2006.01.15 2.4.0 Added support for tagging tiddlers with importSkip, importReplace, and/or importPrivate to enable/disable overwriting or sharing with others when using auto-import macro syntax. Defaults: don't overwrite existing tiddlers, and allow your tiddlers to be auto-imported by others.
2006.01.15 2.3.2 Added "ask" parameter to confirm each tiddler before importing (for use with auto-importing)
2006.01.15 2.3.1 Strip TW core scripts from import source content and load just the storeArea into the hidden IFRAME to prevent imported document's core code from being invoked. Also, when importing local documents, use convertUTF8ToUnicode() to support international characters sets.
2006.01.12 2.3.0 Reorganized code to use callback function for loading import files to support event-driven I/O via an ASYNCHRONOUS XMLHttpRequest instead of waiting for remote hosts to respond to URL requests. Added non-interactive 'batch' mode, using macro parameters to specify source path/file or URL, and select tiddlers to import. Improved messages and added optional 'quiet' switch for batch mode to eliminate //most// feedback.
2006.01.11 2.2.0 Added "[by tags]" to list of tiddlers, based on code submitted by BradleyMeck
2006.01.08 2.1.0 IMPORT FROM ANYWHERE!!! re-write getImportedTiddlers() logic to either read a local file (using local I/O), OR... read a remote file, using a combination of XML and an iframe to permit cross-domain reading of DOM elements. Adapted from example code and techniques courtesy of Jonny LeRoy.
2006.01.06 2.0.2 When refreshing list contents, fixed check for tiddlerExists() when "show differences only" is selected, so that imported tiddlers that don't exist in the current file will be recognized as differences and included in the list.
2006.01.04 2.0.1 When "show differences only" is NOT checked, import all tiddlers that have been selected even when they have a matching title and date.
2005.12.27 2.0.0 Update for TW2.0
Defer initial panel creation and only register a notification function when panel first is created
2005.12.22 1.3.1 tweak formatting in importReport() and add 'discard report' link to output
2005.12.03 1.3.0 Dynamically create/remove importPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding. Also, dynamically create/recreate importFrame each time an external TW document is loaded for importation (reduces DOM overhead and ensures a 'fresh' frame for each document)
2005.11.29 1.2.1 fixed formatting of 'detail info' in importReport()
2005.11.11 1.2.0 added 'inline' param to embed controls in a tiddler
2005.11.09 1.1.0 only load HTML and CSS the first time the macro handler is called. Allows for redundant placement of the macro without creating multiple instances of controls with the same ID's.
2005.10.25 1.0.5 fixed typo in importReport() that prevented reports from being generated
2005.10.09 1.0.4 combined documentation with plugin code instead of using separate tiddlers
2005.08.05 1.0.3 moved CSS and HTML definitions into plugin code instead of using separate tiddlers
2005.07.27 1.0.2 core update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()
2005.07.23 1.0.1 added parameter checks and corrected addNotification() usage
2005.07.20 1.0.0 Initial Release
<<<
On Sunday, November 14, 2010 1:03:43 PM, Adam Warden imported 2 tiddlers from
[[http://tiddlythemes.com/empties/MPTW.html|http://tiddlythemes.com/empties/MPTW.html]]:
<<<
#[[PageTemplate]] - replaces PageTemplate - 8/9/2007 10:12:00 by TiddlyThemes
#[[StyleSheet]] - replaces StyleSheet - 8/9/2007 10:12:00 by TiddlyThemes
<<<
----
On Sunday, November 14, 2010 12:17:17 PM, Adam Warden imported 2 tiddlers from
[[http://tiddlythemes.com/empties/Classic.html|http://tiddlythemes.com/empties/Classic.html]]:
<<<
#[[PageTemplate]] - replaces PageTemplate - 8/9/2007 10:12:00 by TiddlyThemes
#[[StyleSheet]] - replaces StyleSheet - 8/9/2007 10:12:00 by TiddlyThemes
<<<
----
On Sunday, November 14, 2010 9:36:28 AM, PortaDoc imported 2 tiddlers from
[[http://tiddlythemes.com/empties/D3Gtd.html|http://tiddlythemes.com/empties/D3Gtd.html]]:
<<<
#[[PageTemplate]] - added
#[[StyleSheet]] - added
<<<
----
On Sunday, November 14, 2010 1:24:31 AM, Adam Warden imported 36 tiddlers from
[[http://tiddlytools.com|http://tiddlytools.com]]:
<<<
#[[AdvancedOptionsPlugin]] - added
#[[AnalogClock]] - added
#[[AnimationEffectsPlugin]] - added
#[[AnimationEffectsPluginInfo]] - added
#[[AnimationEffectsSampler]] - added
#[[Blackout]] - added
#[[BrightText]] - added
#[[CalendarPlugin]] - added
#[[CalendarPluginConfig]] - added
#[[CycleThemes]] - added
#[[DatePlugin]] - added
#[[DatePluginConfig]] - added
#[[DatePluginInfo]] - added
#[[DefaultTheme]] - added
#[[DigitalClock]] - added
#[[Edge of Night]] - added
#[[Edge of Night Background]] - added
#[[GotoPlugin]] - added
#[[GotoPluginInfo]] - added
#[[Greetings]] - added
#[[HolidayGreetings]] - added
#[[IconPackage]] - added
#[[Let's Get Tanked!]] - added
#[[Let's Get Tanked! Background]] - added
#[[Quotations]] - added
#[[QuoteOfTheDayPlugin]] - added
#[[QuoteOfTheDayPluginInfo]] - added
#[[SinglePageModePlugin]] - added
#[[SinglePageModePluginInfo]] - added
#[[SwitchThemePlugin]] - added
#[[SwitchThemePluginInfo]] - added
#[[The Sky's The Limit]] - added
#[[ThemePackage]] - added
#[[TiddlerPasswordPlugin]] - added
#[[TiddlerPasswordPluginConfig]] - added
#[[TiddlerPasswordPluginInfo]] - added
<<<
/***
|Name|Let's Get Tanked!|
|Source|http://www.TiddlyTools.com/#Let's Get Tanked!|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|CSS|
|Description|theme: dark blue fishtank photo background|
|StyleSheet|Let's Get Tanked!|
|PageTemplateReadOnly|PageTemplateReadOnly|
|EditTemplateReadOnly|EditTemplateReadOnly|
***/
[[StyleSheetAdjustments]]
[[BrightText]]
/* ==== Let's Get Tanked! ==== */
/*{{{*/
body
{ background-image: url('[[Let's Get Tanked! Background]]'); background-attachment: fixed; background-color:#113; }
.menubox
{ background: #003; border:1px solid; -moz-border-radius:1em;-webkit-border-radius:1em; padding:1em }
.viewer
{ background: #003; border:1px solid; -moz-border-radius:1em;-webkit-border-radius:1em; padding:1em; opacity:0.8; filter:'alpha(opacity:80)'; }
#tiddlerWelcome .tabContents
{ opacity:0.9; filter:'alpha(opacity:90)'; }
.header
{ background-image: none; background-color:transparent; color:#ccf; border:0; }
.floatingPanel, .attachPanel, #importPanel, #exportPanel,
{ background: #eef; }
.floatingPanel a, .attachPanel a, #importPanel a, #exportPanel a, #sidebarTabs .tabContents a,
.floatingPanel .button, .attachPanel .button, #importPanel .button, #exportPanel .button, #sidebarTabs .tabContents .button,
.floatingPanel .tiddlyLinkExisting, .attachPanel .tiddlyLinkExisting, #importPanel .tiddlyLinkExisting, #exportPanel .tiddlyLinkExisting, #sidebarTabs .tabContents .tiddlyLinkExisting
{ color:#009; }
.siteMenu .floatingPanel, #messageArea
{ background: #eef; }
.tiddlyCard { background:#ffd; }
.viewer h1,.viewer h2,.viewer h3,.viewer h4,.viewer h5 { background: #666; color:#fff; }
.viewer .tabContents, #sidebarTabs .tabContents
{ background-color:#002; }
.tabContents a, .tabContents .button, .tabContents .tiddlyLinkExisting
{ color:#99f; }
/*}}}*/
!usage
{{{[img[Let's Get Tanked! Background]]}}}
[img[Let's Get Tanked! Background]]
!notes
© 2002 ELS Design Studios - do not copy without prior explicit permission
!type
image/jpg
!file
./images/fish.jpg
!url
http://www.TiddlyTools.com/images/fish.jpg
!data
/***
|''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);
}
//}}}
[[Home]]
[[What is it?]]
[[Get Yours]]
[[Contact]]
[[Calendar]]
<!--{{{-->
<div class='header' 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>
<!-- horizontal MainMenu -->
<div id='topMenu' refresh='content' tiddler='MainMenu'></div>
<!-- original MainMenu menu -->
<!-- <div id='mainMenu' refresh='content' tiddler='MainMenu'></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'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/***
|''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"
});
*/
//}}}
PortaDoc is a term describing a Portable Document. The core shell is made from http://www.tiddlywiki.com
The way to learn to use TiddlyWiki is to forget that you don't know how to use TiddlyWiki...
----
"Knock, Knock"... "Who's there?"... "Oh! I guess you know that one..."
----
In theory, there is no difference between theory and practice. But, in practice, there is.
----
Sometimes when reading Goethe I have the paralyzing suspicion that he is trying to be funny.
----
A witty saying proves nothing.
----
The problem with some people is that when they aren't drunk, they're sober.
----
The great thing about television is that if something important happens anywhere in the world, day or night, you can always change the channel.
----
Don't be so humble - you are not that great.
----
The combination "ough" can be pronounced in nine different ways. The following sentence contains them all: "A rough-coated, dough-faced, thoughtful ploughman strode through the streets of Scarborough; after falling into a slough, he coughed and hiccoughed."
----
If you lived here, you'd be home by now...
----
I love my dust. It shows I had something better to do.
----
Time flies like an arrow... Fruit flies like a banana [Groucho Marx]
----
If you don't know where you're going, you'll probably end up somewhere else.
----
Weebles wobble... but they don't fall down!
----
It's all very simple... or else it's all very complex... or perhaps it's neither... or both.
----
Accepting reality is the first step to insanity
----
Oops! Sorry. My karma ran over your dogma.
----
If it looks like a duck, walks like a duck and sounds like a duck, it's probably something else.
----
Some times you feel like a nut, some times you bolt.
----
Santaclaustrophobia... The feeling that Christmas is closing in all around you.
----
Why is abbreviation such a long word?
----
Diplomacy is the art of saying 'Nice doggie!'... until you can find a rock.
----
Scientists working on cloning technology have done what the american educational system has been doing for years - producing identical sheep.
----
Umm... What's another word for thesaurus?
----
Give me ambiguity or give me something else
----
Don't anthropomorphize your computer, it doesn't like it.
----
Ninth Law of Cartoon Physics: Everything falls faster than an anvil.
----
Oh yeah? Far out!
----
Boycott Shampoo - Demand the REAL poo!
----
Remember: Don't sweat the petty things... and don't pet the sweaty things.
----
Sign in lunch room: "Shoes are required to eat in the cafeteria..." (and hand-written below: "...socks can eat anywhere they want.")
----
Don't be irreplaceable, if you can't be replaced, you can't be promoted.
----
5 out of 4 people have problems with fractions...
----
Osborne's Law of Mathematics: Variables won't; constants aren't.
----
Always remember you're unique, just like everyone else.
----
Something to ponder: What was the best thing *before* sliced bread? Hmmm...
----
Physics Joke #27: Two hydrogen atoms bump into each other while walking down the street: 'Are you alright?'... 'No, I lost an electron!'... 'Are you sure?'... 'Yeah, I'm Positive!'
----
The one thing I can't stand is intolerant people!
----
Old programmers never die. . . they just can't C as well.
----
World Shortest 'Bar' joke: A guy walks into a bar... OUCH! he says...
----
Never judge a man 'til you have walked a mile in his shoes, because by then, he's a mile away, you've got his shoes, and you can say whatever the hell you want to.
----
The problem with troubleshooting is that real trouble shoots back.
----
These are the roots of rhythm: boom, de boom, de-boom, ding-dong, ooh! [Leila ~Gallagher-Breen]
----
These are the roots of music: boom-chicky-chicky boom, meow, meow, baddom, baddom, ding-aling-a-long, chicky-boom! [Leila ~Gallagher-Breen]
----
Classified ad (in Physics Quarterly): Got Mole problems? Call Avagadro Exterminators: 602-1023
----
He who laughs last thinks slowest
----
Would a fly without wings be called a walk?
----
The winner of the World's Worst Analogy contest: 'The little boat glided across the water in exactly the way a bowling ball wouldn't.'
----
From the 'say what?!?' files: We are ready for any unforeseen event that may or may not occur. [Dan Quayle 9/22/90]
----
I believe you should live each day as if it is your last, which is why I don't have any clean laundry because, come on, who wants to wash clothes on the last day of their life? [Jack Handy]
----
PRINTER - A device consisting of three main parts: the case, the jammed paper tray, and the blinking red light.
----
Dilbert's Laws of Work: The more crap you put up with, the more crap you are going to get.
----
Q: Why'd the electron cross the road? A: 'Cause he was already on the other side...
----
When the going gets tough, remember STRESSED spelled backwards is DESSERTS.
----
Foobar... baz. Mumble: frotz, gronk, snork. Snerfle? Natter and gromish!
----
Pentiums melt in your PC, not in your hand.
----
everyone is cute... even me. But in purple... I'm STUNNING!! [Londo Mollari]
----
I always wanted to be somebody, but I should have been more specific. [Lily Tomlin]
----
It's OK to change horses in mid-stream, especially if the first horse can't swim! [Laura Shulman]
----
Work is the curse of the drinking classes. [Oscar Wilde]
----
We have only two things to worry about: That things will never get back to normal, and that they already have.
----
Intelligence is a funny thing: those who don't have it think they do, and those who do are smart enough to know better.
----
Life is hard, Love is strange. Nothing lasts, people change. Dream of a long and wonderful future, but live now.
----
'Can you prove any of the stuff you believe in?', my friend asked. When I said that's not how belief works, he nodded and said that's what he thought but he was just checking to make sure he hadn't missed a key point.
----
Life ... It's a good place to be!
----
Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail.
----
History is made at night... character is what you are in the dark. [Dr. Emilio Lizardo, aka Lord John Worfin]
----
You can't always get what you want... but if you try sometimes, you just may find, that you get what you need. [The Rolling Stones]
----
The only man who behaved sensibly was my tailor; he took my measurement anew every time he saw me, while all the rest went on with their old measurements and expected them to fit me. [George Bernard Shaw]
----
In matters of style, swim with the current: in matters of principle, stand like a rock. [Thomas Jefferson]
----
Great things are not done by impulse, but by a series of small things brought together. [Vincent van Gogh]
----
'I think there is a world market for maybe five computers.' [Thomas Watson, chairman of IBM, 1943]
----
We have to live today by what truth we can get today, and be ready tomorrow to call it falsehood. [William James]
----
There are two ways of spreading light: to be the candle or the mirror that reflects it. [Edith Wharton]
----
Talent develops in tranquility, character in the full current of human life. [Johann Wolfgang von Goethe (1749-1832)]
----
Our firmest convictions are apt to be the most suspect; they mark our limitations and our bounds. Life is a petty thing unless it is moved by the indomitable urge to extend its boundaries. [Jose Ortega y Gasset]
----
It takes courage to grow up and turn out to be who you really are. [e e cummings (1894-1962)]
----
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]
----
Quiet minds cannot be perplexed or frightened, but go on in fortune or misfortune at their own private pace, like a clock during a thunderstorm. [Robert Louis Stevenson]
----
In the struggle between yourself and the world, second the world. [Franz Kafka]
----
Every man's condition is a solution in hieroglyph to those inquiries he would put. He acts it as life before he apprehends it as truth. [Ralph Waldo Emerson]
----
One can remain alive...if one is unafraid of change, insatiable in intellectual curiosity, interested in big things, and happy in small ways. [Edith Wharton]
----
a rock is like space because it doesnt move; and space is like a rock because it is empty. words are buddhas. [Jack Kerouac]
----
The whole problem with the world is that fools and fanatics are always so certain of themselves, and wiser people so full of doubts. [Bertrand Russell]
----
Doubt is not a pleasant state of mind, but certainty is absurd. [Voltaire]
----
Education is not the filling of a pail, but the lighting of a fire. [William Butler Yeats]
----
If you take yourself too seriously, no one else will take you seriously enough... [Eric Shulman]
----
There are only four questions of value in life... What is sacred? Of what is the spirit made? What is worth living for, and what is worth dying for? The answer to each is the same: only love. [Don Juan ~DeMarco]
----
If you are a dreamer, come in. If you are a dreamer, a wisher, a liar, a hope-er, a pray-er, a magic bean buyer... If you're a pretender, come sit by my fire... For we have some flax-golden tales to spin. Come in! Come in! [Shel Silverstein]
----
O money, money, money, I'm not necessarily one of those who think thee holy, But I often stop to wonder how thou canst go out so fast when thou comest in so slowly. [Ogden Nash]
----
There is no progress without struggle. [Frederick Douglass]
----
Before you can do something, you must become something. [Goethe]
----
The man who follows the crowd will usually get no further than the crowd. The man who walks alone is likely to find himself in places no one has ever been. [Alan ~Ashley-Pit]
----
Weep not for the dead for they are but empty cages from which the bird has flown. [Tibetan Book of The Dead]
----
I wish it would dawn upon engineers that, in order to be an engineer, it is not enough to be an engineer. [Jose Ortega y Gasset]
----
Every exit is an entry somewhere. [Tom Stoppard]
----
Wherever we are, it is but a stage on the way to somewhere else, and whatever we do, however well we do it, it is only a preparation to do something else that shall be different. [Robert Louis Stevenson]
----
We judge ourselves by what we feel capable of doing, while others judge us by what we have already done. [Henry Wadsworth Longfellow]
----
All our words are but crumbs that fall down from the feast of the mind. [Kahlil Gibran, "Sand and Foam"]
----
It's a lot harder to find joy than it is to find bread. Feed your soul first, then go shopping. [Eric Shulman]
----
Why do you hasten to remove anything which hurts your eye, while if something affects your soul you postpone the cure until next year? [Horace]
----
Not to know is bad. Not to want to know is worse. Not to hope is unthinkable. Not to care is unforgivable. [Nigerian folk saying]
----
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']
----
There are no shortcuts to anyplace worth going. [Beverly Sills]
----
Somewhere, something incredible is waiting to be known. [Carl Sagan]
----
Courage is the price that Life extracts for granting peace. [Amelia Earhart]
----
Great things are not done by impulse, but by a series of small things brought together. [Vincent van Gogh]
----
Choose a job you love, and you will never have to work a day in your life. [Confucius]
----
There is only one success - to be able to spend your life in your own way. [Christopher Morley]
----
We choose our joys and sorrows long before we experience them. [Kahlil Gibran]
----
It is all a frame of mind, this enjoyment of living. [Lin Yutang]
----
Work for something because it is good, not just because it stands a chance to succeed. [Vaclav Havel]
----
The easiest way to get what you want is to help others get what they want. [Deepak Chopra]
----
All generalizations are false, including this one. [Bucky Radfish]
----
In science, 'fact' can only mean 'confirmed to such a degree that it would be perverse to withhold provisional assent.' I suppose that apples might start to rise tomorrow, but the possibility does not merit equal time in physics classrooms. [Stephen Jay Gould (1941 - 2002)]
----
Twenty years from now, you will be more disappointed by the things you didn't do, than by the ones you did. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails. Explore, dream... [Mark Twain]
----
To live only for some future goal is shallow. It's the sides of the mountain that sustain life, not the top. [Robert M. Pirsig]
----
Nothing is so contagious as enthusiasm; it moves stones, it charms brutes. Enthusiasm is the genius of sincerity, and truth accomplishes no victories without it. [Edward G. E. ~Bulwer-Lytton (1803 - 1873)]
----
The past is but the beginning of a beginning, and all that is and has been is but the twilight of the dawn. [Herbert George Wells]
----
We grow great by dreams. All big men are dreamers. They see things in the soft haze of a spring day or in the red fire of a long winter's evening. Some of us let these great dreams die, but others nourish and protect them; nurse them through bad days till they bring them to the sunshine and light, which comes always to those who sincerely hope that their dreams will come true. [Woodrow Wilson]
----
Be brave enough to live life creatively. The creative is the place where no one else has ever been. You have to leave the city of your comfort and go into the wilderness of your intuition. You can't get there by bus, only by hard work and risk and by not quite knowing what you're doing. What you'll discover will be wonderful. What you'll discover will be yourself. [Alan Alda]
----
If we had no winter, the spring would not be so pleasant; if we did not sometimes taste of adversity, prosperity would not be so welcome.
----
Solitude, if rightly used, becomes not only a privilege but a necessity. Only a superficial soul fears to fraternize with itself.
----
One of the symptoms of an approaching nervous breakdown is the belief that one's work is terribly important.
----
Hope is like a road in the country: there was never a road, but when many people walk on it, the road comes into existence.
----
You can only find truth with logic if you have already found truth without it.
----
Love is always bestowed as a gift - freely, willingly and without expectation. We don't love to be loved; we love to love.
----
Always listen to experts. They'll tell you what can't be done, and why. Then do it.
----
Distance between two hearts is not an obstacle; rather a great reminder of just how strong true love can be.
----
Not everything that can be counted counts, and not everything that counts can be counted.
----
Life's challenges are not supposed to paralyze you, they're supposed to help you discover who you are.
----
Nothing splendid has ever been achieved except by those who dared believe that something inside them was superior to circumstances.
----
Whether you think that you can, or that you can't, you are usually right.
----
The only time you run out of chances is when you stop taking them.
----
Knowledge speaks, but wisdom listens.
----
Too often we give our children answers to remember rather than problems to solve.
----
Books are the shoes with which we tread the footsteps of great minds. A book may lie dormant for fifty years or for two thousand years in a forgotten corner of a library, only to reveal, upon being opened, the marvels or the abysses that it contains, or the line that seems to have been written for me alone. In this respect the writer is not different from any other human being: whatever we say or do can have far-reaching consequences.
----
A people that values its privileges above its principles soon loses both.
----
Treat everyone with politeness, even those who are rude to you. Not because they are nice, but because you are.
----
The ultimate measure of a man is not where he stands in moments of comfort and convenience, but where he stands in times of challenge and controversy. What lies behind us and what lies before us, are only small matters compared to what lies within us.
----
In your presence even my shadow acquires the sensation of touch.
----
Being in charge of your own reality is a little tougher; it takes a lot of thinking and brutal honesty. [Phil Glatz]
----
There are always going to be amazingly creative people doing wonderful things. [Phil Glatz]
----
The trick is to rise above the symptoms of being aware, and actually BE aware. [Phil Glatz]
----
A revolution is coming - a revolution which will be peaceful if we are wise enough; compassionate if we care enough; successful if we are fortunate enough - but a revolution which is coming whether we will it or not. We can affect its character, we cannot alter its inevitability. [John F. Kennedy]
----
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.
----
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]
/***
|Name|QuoteOfTheDayPlugin|
|Source|http://www.TiddlyTools.com/#QuoteOfTheDayPlugin|
|Documentation|http://www.TiddlyTools.com/#QuoteOfTheDayPluginInfo|
|Version|1.4.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|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|QuoteOfTheDayPluginInfo|
|Source|http://www.TiddlyTools.com/#QuoteOfTheDayPlugin|
|Documentation|http://www.TiddlyTools.com/#QuoteOfTheDayPluginInfo|
|Version|1.4.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|Documentation for QuoteOfTheDayPlugin|
!!!!!Usage
<<<
{{{<<QOTD tiddlername norandom noclick inline cookie:cookiename delay>>}}}
* ''tiddlername'' is the name of a tiddler containing your list of quotes, each separated by a horizontal line (use {{{----}}} on a line by itself).
* Each time the macro is rendered it will display a different quotation, selected at random from the specified tiddler. To display quotes in the sequence in which they occur in the tiddler, you can use the ''norandom'' keyword.
* When using ''norandom'', you can also specify an optional ''cookie:cookiename'' parameter which will be used to track the //index// of the next quote to be displayed, so that each subsequent rendering of the macro can continue the sequence of quotes as entered in the source tiddler, even in between browser sessions.
* By default, clicking on the rendered quote will select and display another random quote. Use the optional ''noclick'' keyword parameter to disable this "onClick" handling.
* By default, a clickable or timed quote will be displayed insider a 'slider' panel, so that standard TW animation effects will be used. However, slider panels are always rendered as "block-level" content, forcing a newline both before and after the slider panel. Use the ''inline'' keyword parameter to bypass this side-effect and display a clickable/timed quote without automatically adding surrounding linebreaks.
* The quote can also be refreshed automatically, by specifying a numeric ''delay'' parameter (in milliseconds) which enables a countdown timer. When the mouse is over the quote, the timer is automatically stopped. Moving the mouse away from the quote content restarts the timer.
<<<
!!!!!Example
<<<
{{{<<QOTD Quotations 10000>>}}}
<<QOTD Quotations 10000>>
<<<
!!!!!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.
2008.01.16 1.4.0 support using a local image file directory instead of tiddler name for getting list of items. If specified tiddler does not exist in the document, macro attempts to use tiddlername as a local directory name (using either absolute or relative path) and get list of all JPG/GIF/PNG files.
2007.08.06 1.3.0 added support for "cookie:cookiename" param
2007.05.03 1.2.1 corrected logic for handling "inline" display (i.e., bypass slider and use of 'block' for quote elements)
2007.05.03 1.2.0 added sliderPanel wrapper around quote to take advantage of core-supported slider animation. Use "noslider"/"inline" keyword param to suppress use of slider. Also added tooltips for click, delay, and click+delay modes.
2007.04.16 1.1.2 code cleanup
2007.04.16 1.1.1 onClick handling now supports sequential as well as random order
2007.04.14 1.1.0 added onClick handling for selecting and display a new random quote
2005.10.21 1.0.0 Initial Release. Based on a suggestion by M.Russula
<<<
<<slider chkContents SideBarTabs##contents contents contents>>/%
!contents
<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>
!end
%/
/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.6|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|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;
}
//}}}
/***
|Name|SinglePageModePluginInfo|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.6|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|Documentation for SinglePageModePlugin|
Normally, as you click on the links in TiddlyWiki, more and more tiddlers are displayed on the page. The order of this tiddler display depends upon when and where you have clicked. Some people like this non-linear method of reading the document, while others have reported that when many tiddlers have been opened, it can get somewhat confusing. SinglePageModePlugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one item displayed at a time.
!!!!!Usage
<<<
When the plugin is enabled, only one tiddler will be displayed at a time and the browser window's titlebar is updated to include the current tiddler title. The browser's location URL is also updated with a 'permalink' for the current tiddler so that it is easier to create a browser 'bookmark' for the current tiddler. Alternatively, even when displaying multiple tiddlers //is// permitted, you can still reduce the potential for confusion by forcing tiddlers to always open at the top (or bottom) of the page instead of being displayed following the tiddler containing the link that was clicked.
<<<
!!!!!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:
* {{block{
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}}}. You can also use {{{SPM:expression}}}, where 'expression' is any javascript statement that evaluates to true or false. This allows you to create hard-coded links in other documents that can selectively enable/disable the use of this option based on various programmatic conditions, such as the current username. For example, using
{{{#SPM:config.options.txtUserName!="SomeName"}}}
enables 'one tiddler at a time' display for all users //other than// "~SomeName")}}}
* 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
2008.06.12 2.9.5 corrected 'scroll to top of page' logic in auto-scroll handling
2008.06.11 2.9.4 added chkSinglePageKeepEditedTiddlers option
2008.06.05 2.9.3 in displayTiddler(), bypass single/top/bottom mode handling if startingUp. Allows multiple tiddlers to be displayed during startup processing (e.g., #story:DefaultTiddlers), even if single/top/bottom mode is enabled.
2008.04.18 2.9.2 in displayTiddler() and checkLastURL(), handling for Unicode in tiddler titles (remove explicit conversion between Unicode and UTF, as this is apparently done automatically by encode/decodeURIComponent, resulting in double-encoding!
2008.04.08 2.9.1 don't automatically add options to AdvancedOptions shadow tiddler
2008.04.02 2.9.0 in displayTiddler(), when single-page mode is in use and a tiddler is being edited, ask for permission to save-and-close that tiddler, instead of just leaving it open.
2008.03.29 2.8.3 in displayTiddler(), get title from tiddler object (if needed). Fixes errors caused when calling function passes a tiddler *object* instead of a tiddler *title*
2008.03.14 2.8.2 in displayTiddler(), if editing specified tiddler, just move it to top/bottom of story *without* re-rendering (prevents discard of partial edits).
2008.03.06 2.8.1 in paramifier handler, start 'checkURL' timer if chkSinglePageMode is enabled
2008.03.06 2.8.0 added option, {{{config.options.chkSinglePageKeepFoldedTiddlers}}}, so folded tiddlers won't be closed when using single-page mode. Also, in checkURL(), if hash is a ''permaview'' (e.g., "#foo bar baz"), then display multiple tiddlers rather than attempting to display "foo bar baz" as a single tiddler
2008.03.05 2.7.0 added support for "SPM:" URL paramifier
2008.03.01 2.6.0 in hijack of displayTiddler(), added 'title' argument to closeAllTiddlers() so that target tiddler isn't closed-and-reopened if it was already displayed. Also, added config.options.chkSinglePageAutoScrolloption to bypass automatic 'scroll into view' logic (note: core still does it's own ensureVisible() handling)
2007.12.22 2.5.3 in checkLastURL(), use decodeURIComponent() instead of decodeURI so that tiddler titles with commas (and/or other punctuation) are correctly handled.
2007.10.26 2.5.2 documentation cleanup
2007.10.08 2.5.1 in displayTiddler(), when using single-page or top-of-page mode, scrollTo(0,0) to ensure that page header is in view.
2007.09.13 2.5.0 for TPM/BPM modes, don't force tiddler to redisplay if already shown. Allows transition between view/edit or collapsed/view templates, without repositioning displayed tiddler.
2007.09.12 2.4.0 added option to disable automatic permalink feature. Also, Safari is now excluded from permalinking action to avoid bug where tiddlers don't display after hash is updated.
2007.03.03 2.3.1 fix typo when adding BPM option to AdvancedOptions (prevented checkbox from appearing)
2007.03.03 2.3.0 added support for BottomOfPageMode (BPM) based on request from DaveGarbutt
2007.02.06 2.2.3 in Story.prototype.displayTiddler(), use convertUnicodeToUTF8() for correct I18N string handling when creating URL hash string from tiddler title (based on bug report from BidiX)
2007.01.08 2.2.2 use apply() to invoke hijacked core functions
2006.07.04 2.2.1 in hijack for displayTiddlers(), suspend TPM as well as SPM so that DefaultTiddlers displays in the correct order.
2006.06.01 2.2.0 added chkTopOfPageMode (TPM) handling
2006.02.04 2.1.1 moved global variable declarations to config.* to avoid FireFox 1.5.0.1 crash bug when assigning to globals
2005.12.27 2.1.0 hijack displayTiddlers() so that SPM can be suspended during startup while displaying the DefaultTiddlers (or #hash list). Also, corrected initialization for undefined SPM flag to "false", so default behavior is to display multiple tiddlers
2005.12.27 2.0.0 Update for TW2.0
2005.11.24 1.1.2 When the back and forward buttons are used, the page now changes to match the URL. Based on code added by Clint Checketts
2005.10.14 1.1.1 permalink creation now calls encodeTiddlyLink() to handle tiddler titles with spaces in them
2005.10.14 1.1.0 added automatic setting of window title and location bar ('auto-permalink'). feature suggestion by David Dickens.
2005.10.09 1.0.1 combined documentation and code in a single tiddler
2005.08.15 1.0.0 Initial Release
<<<
The portable reusable non-linear personal web notebook
[img[http://lh4.ggpht.com/_I-6MAVwe7WY/TN962uk6pLI/AAAAAAAAJys/KV7AB__rq7k/smileySun.png]] PortaDoc
/*{{{*/
/* a contrasting background so I can see where one tiddler ends and the other begins */
body {
background: [[ColorPalette::TertiaryLight]];
}
/* sexy colours and font for the header */
.headerForeground {
color: [[ColorPalette::PrimaryPale]];
}
.headerShadow, .headerShadow a {
color: [[ColorPalette::PrimaryMid]];
}
.headerForeground, .headerShadow {
padding: 1em 1em 0;
font-family: 'Trebuchet MS' sans-serif;
font-weight:bold;
}
.headerForeground .siteSubtitle {
color: [[ColorPalette::PrimaryLight]];
}
.headerShadow .siteSubtitle {
color: [[ColorPalette::PrimaryMid]];
}
/* make shadow go and down right instead of up and left */
.headerShadow {
left: 1px;
top: 1px;
}
/* prefer monospace for editing */
.editor textarea {
font-family: 'Consolas' monospace;
}
/* sexy tiddler titles */
.title {
font-size: 250%;
color: [[ColorPalette::PrimaryLight]];
font-family: 'Trebuchet MS' sans-serif;
}
/* more subtle tiddler subtitle */
.subtitle {
padding:0px;
margin:0px;
padding-left:0.5em;
font-size: 90%;
color: [[ColorPalette::TertiaryMid]];
}
.subtitle .tiddlyLink {
color: [[ColorPalette::TertiaryMid]];
}
/* a little bit of extra whitespace */
.viewer {
padding-bottom:3px;
}
/* don't want any background color for headings */
h1,h2,h3,h4,h5,h6 {
background: [[ColorPalette::Background]];
color: [[ColorPalette::Foreground]];
}
/* give tiddlers 3d style border and explicit background */
.tiddler {
background: [[ColorPalette::Background]];
border-right: 2px [[ColorPalette::TertiaryMid]] solid;
border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
margin-bottom: 1em;
padding-bottom: 2em;
}
/* make options slider look nicer */
#sidebarOptions .sliderPanel {
border:solid 1px [[ColorPalette::PrimaryLight]];
}
/* the borders look wrong with the body background */
#sidebar .button {
border-style: none;
}
/* displays the list of a tiddler's tags horizontally. used in ViewTemplate */
.tagglyTagged li.listTitle {
display:none
}
.tagglyTagged li {
display: inline; font-size:90%;
}
.tagglyTagged ul {
margin:0px; padding:0px;
}
/* this means you can put line breaks in SidebarOptions for readability */
#sidebarOptions br {
display:none;
}
/* undo the above in OptionsPanel */
#sidebarOptions .sliderPanel br {
display:inline;
}
/* horizontal main menu stuff */
#displayArea {
margin: 1em 15.7em 0em 1em; /* use the freed up space */
}
#topMenu br {
display: none;
}
#topMenu {
background: [[ColorPalette::PrimaryMid]];
color:[[ColorPalette::PrimaryPale]];
}
#topMenu {
padding:2px;
}
#topMenu .button, #topMenu .tiddlyLink, #topMenu a {
margin-left: 0.5em;
margin-right: 0.5em;
padding-left: 3px;
padding-right: 3px;
color: [[ColorPalette::PrimaryPale]];
font-size: 115%;
}
#topMenu .button:hover, #topMenu .tiddlyLink:hover {
background: [[ColorPalette::PrimaryDark]];
}
/* make it print a little cleaner */
@media print {
#topMenu {
display: none ! important;
}
/* not sure if we need all the importants */
.tiddler {
border-style: none ! important;
margin:0px ! important;
padding:0px ! important;
padding-bottom:2em ! important;
}
.tagglyTagging .button, .tagglyTagging .hidebutton {
display: none ! important;
}
.headerShadow {
visibility: hidden ! important;
}
.tagglyTagged .quickopentag, .tagged .quickopentag {
border-style: none ! important;
}
.quickopentag a.button, .miniTag {
display: none ! important;
}
}
/*}}}*/
/***
|Name|SwitchThemePlugin|
|Source|http://www.TiddlyTools.com/#SwitchThemePlugin|
|Documentation|http://www.TiddlyTools.com/#SwitchThemePluginInfo|
|Version|5.4.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.3|
|Type|plugin|
|Description|Select alternative TiddlyWiki template/stylesheet 'themes' from a droplist|
!!!!!Documentation
>see [[SwitchThemePluginInfo]]
!!!!!Configuration
<<<
Current theme:<<switchTheme width:auto>>
<<option chkRandomTheme>> select a random theme at startup
//Note: to prevent a given theme from being chosen at random, tag it with <<tag excludeTheme>>//
<<<
!!!!!Installation Note
>As of 4/13/2008, a "core patch" function that provides backward-compatibility with TW2.3.x has been split into a separate tiddler, [[SwitchThemePluginPatch]], to reduce installation overhead for //this// plugin. ''You should only install the patch tiddler when using this plugin in documents based on a core version prior to TW2.4.0''
!!!!!Revisions
<<<
2009.10.01 [5.4.1] changed 'noRandom' tag to 'excludeTheme' and recognize 'excludeLists' tag
| Please see [[SwitchThemePluginInfo]] for previous revision details |
2008.01.22 [5.0.0] Completely re-written and renamed from [[SelectStylesheetPlugin]] (now retired)
//history for retired SelectStylesheetPlugin omitted//
2005.07.20 [1.0.0] initial release (as SelectStylesheetPlugin)
<<<
!!!!!Code
***/
//{{{
version.extensions.SwitchThemePlugin= {major: 5, minor: 4, revision: 1, date: new Date(2009,10,1)};
config.macros.switchTheme = {
handler: function(place,macroName,params) {
setStylesheet(".switchTheme {width:100%;font-size:8pt;margin:0em}","switchThemePlugin");
if (params[0] && (params[0].substr(0,6)=="width:")) var width=(params.shift()).substr(6);
if (params[0] && (params[0].substr(0,6)=="label:")) var label=(params.shift()).substr(6);
if (params[0] && (params[0].substr(0,7)=="prompt:")) var prompt=(params.shift()).substr(7);
if (params[0] && params[0].trim().length) // create a link that sets a specific theme
createTiddlyButton(place,label?label:params[0],prompt?prompt:params[0],
function(){ config.macros.switchTheme.set(params[0]); return false;});
else { // create a select list of available themes
var theList=createTiddlyElement(place,"select",null,"switchTheme",null);
theList.size=1;
if (width) theList.style.width=width;
theList.onchange=function() { config.macros.switchTheme.set(this.value); return true; };
this.refresh(theList);
}
},
refresh: function(list) {
var indent = String.fromCharCode(160)+String.fromCharCode(160);
while(list.length > 0){list.options[0]=null;} // clear list
list.options[list.length] = new Option("select a theme:","",true,true);
list.options[list.length] = new Option(indent+"[default]","StyleSheet");
list.options[list.length] = new Option(indent+"[random]","*");
var themes=store.getTaggedTiddlers("systemTheme");
for (var i=0; i<themes.length; i++)
if (themes[i].title!="StyleSheet" && !themes[i].isTagged('excludeLists'))
list.options[list.length]=new Option(indent+themes[i].title,themes[i].title);
// show current selection
for (var t=0; t<list.options.length; t++)
if (list.options[t].value==config.options.txtTheme)
{ list.selectedIndex=t; break; }
},
set: function(theme) {
if (!theme||!theme.trim().length) return;
if (theme=="*") { // select a random theme (except themes with "excludeTheme")
var curr=config.options.txtTheme;
var themes=store.getTaggedTiddlers("systemTheme");
if (!themes.length) return false;
var which=Math.floor(Math.random()*themes.length);
while (themes[which].title==curr
||themes[which].tags.contains('excludeTheme','excludeLists'))
which=Math.floor(Math.random()*themes.length);
theme=themes[which].title;
}
// apply selected theme
story.switchTheme(theme);
// sync theme droplists
var elems=document.getElementsByTagName("select");
var lists=[]; for (var i=0; i<elems.length; i++)
if (hasClass(elems[i],"switchTheme")) lists.push(elems[i]);
for (var k=0; k<lists.length; k++)
for (var t=0; t<lists[k].options.length; t++)
if (lists[k].options[t].value==config.options.txtTheme)
{ lists[k].selectedIndex=t; break; }
return;
}
}
//}}}
// // option to select a random theme at startup (if enabled)
//{{{
if (config.options.chkRandomTheme===undefined)
config.options.chkRandomTheme=false;
if (config.options.chkRandomTheme)
config.macros.switchTheme.set("*");
//}}}
// // hijack switchTheme to add Check/Init/Reset code handlers
//{{{
if (Story.prototype.switchTheme_saved===undefined) { // only once
Story.prototype.switchTheme_saved=Story.prototype.switchTheme;
Story.prototype.switchTheme=function(t){
function run(t,s){
var f=store.getTiddlerText(store.getTiddlerSlice(t,s));
return f?eval('(function(){\n'+f+'\n})()'):false;
}
if (!startingUp && (run(config.options.txtTheme,'Reset')||run(t,'Check'))) return;
this.switchTheme_saved.apply(this,arguments);
run(t,'Init');
}
}
//}}}
/***
|Name|SwitchThemePluginInfo|
|Source|http://www.TiddlyTools.com/#SwitchThemePlugin|
|Documentation|http://www.TiddlyTools.com/#SwitchThemePluginInfo|
|Version|5.4.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.3|
|Type|documentation|
|Description|documentation for SwitchThemePlugin|
This plugin replaces the features previously provided by SelectStylesheetPlugin (which has been retired from distribution because it is no longer compatible with the current release of the TiddlyWiki core). ''//This plugin requires TiddlyWiki version 2.3.0 or later//''
!!!!!Usage
<<<
{{medium{__Defining a theme:__}}}
First, create/import a tiddler containing CSS definitions and tag it with<<tag systemTheme>>. At the top of the tiddler, embed a //slice table// with at least one slice, "~StyleSheet", whose value is the name of the tiddler itself, e.g., in a tiddler called [[MyTheme]], write:
{{{
/***
|StyleSheet|MyTheme|
***/
}}}
>Note use of {{{/***}}} and {{{***/}}} around the slice table. This special ~TiddlyWiki comment syntax permits the browser to ignore any wiki-syntax that has been embedded within the tiddler while still processing the ~CSS-syntax it contains.
A theme tiddler can also define one or more additional slices that associate customized versions of [[PageTemplate]], [[ViewTemplate]], and/or [[EditTemplate]], for use with that theme:
{{{
/***
|PageTemplate|MyPageTemplate|
|ViewTemplate|MyViewTemplate|
|EditTemplate|MyEditTemplate|
***/
}}}
where the slice //name// is the standard template name, and the slice //value// is the title of the alternative custom template to use. You can also associate a secondary set of ''"read only" templates that will be automatically applied whenever a document is being viewed online'' (i.e., via http: protocol)
{{{
|PageTemplateReadOnly|MyWebPageTemplate|
|ViewTemplateReadOnly|MyWebViewTemplate|
|EditTemplateReadOnly|MyWebEditTemplate|
}}}
These alternative templates can be used to present a reduced-feature "reader" interface when viewed on-line by others, while still offering a full-featured "author" interface when working locally.
It is also possible to defines slices that invoke custom javascript code whenever theme switching occurs. Each theme can include three special slices:
{{{
|Check|MyThemeCheck|
|Init|MyThemeInit|
|Reset|MyThemeReset|
}}}
These slices refer to tiddlers (or tiddler sections) containing javascript code.
*{{block{
The code referenced by the ''Check'' slice (if any) is invoked ''before switching'' to a selected theme. ''If this code returns a non-zero (or true) result, then the new theme will not be applied. A zero (or false) value allows the theme switch to continue as usual.'' For example, the following code asks for confirmation, allowing the user to cancel the theme switch:
{{{
return !confirm('Are you sure you want to use this theme?');
}}}
}}}
*After a theme has been applied, the code referenced by the ''Init'' slice (if any) is invoked. This can be used to perform theme-related ''side-effects'', such as modifying various {{{config.options['...']}}} settings or displaying instructions/messages.
*When switching to another theme, any code referenced by a ''Reset'' slice //in the current theme// is invoked before the new theme is applied. ''If this code returns a non-zero result, then the new theme will not be applied.'' As with the ''Check'' code, this can be used to ask the user to confirm before switching themes. However, the primary intent of the ''Reset'' code is to permit restoration any modified settings that were altered by ''Init'' code that was previously invoked for the current theme.
{{medium{__Selecting a theme from a droplist:__}}}
To display a droplist of available themes, use this syntax:
{{{
<<switchTheme width:nnn>>
}}}
*''width:nnn[cm|px|em|%]'' (optional)<br>specifies the width of the droplist (using CSS measurements)(default=100%)
All tiddlers tagged with<<tag systemTheme>> will be included in the droplist of available themes for you to select (except those also tagged with <<tag excludeLists>>. The current selection is stored in a TiddlyWiki option cookie ("txtTheme") that is applied automatically each time you reload your document. If the selected theme does not exist in the document (e.g., it was deleted/renamed after being selected), the [default] CSS tiddler, [[StyleSheet]], will be used as a fallback. If [random] is seleced, the plugin automatically selects a random theme. You can exclude a theme from being randomly selected by tagging it with <<tag excludeTheme>>.
Example:
{{{<<switchTheme width:30%>>}}}
<<switchTheme width:30%>>
{{medium{__Selecting a theme from a command link:__}}}
The {{{<<switchTheme>>}}} macro can also be used to embed a command link that, when clicked, will apply a specific, pre-selected theme, using the following syntax:
{{{
<<switchTheme "label:link text" "prompt:tooltip text" TiddlerName>>
}}}
* ''label:text'' and ''prompt:text'' (optional)<br>define the link text the 'tooltip' text that appears near the mouse pointer when placed over the link, respectively.
*''~TiddlerName''<br>specifies the name of the theme tiddler to be applied (e.g., {{{<<switchTheme [[Woodshop]]>>}}}
Examples:
{{{
<<switchTheme Plain>>
<<switchTheme Blackout>>
<<switchTheme Woodshop>>
<<switchTheme Textures>>
<<switchTheme [[Edge of Night]]>>
<<switchTheme label:[default] StyleSheet>>
<<switchTheme label:randomize *>>
}}}
<<switchTheme Plain>> <<switchTheme Blackout>> <<switchTheme Woodshop>> <<switchTheme Textures>> <<switchTheme [[Edge of Night]]>> <<switchTheme label:[default] StyleSheet>> <<switchTheme label:randomize *>>
NOTE:
>You can also create a command link that specifies "*" for the theme name. This will select a theme //at random// from the list of available themes. To prevent a given theme from being selected, tag it with <<tag excludeTheme>>.
<<<
!!!!!Configuration
<<<
<<option chkRandomTheme>> select a random theme at startup
//Note: to prevent a given theme from being chosen at random, tag it with <<tag excludeTheme>>//
<<<
!!!!!Revisions
<<<
2009.10.01 5.4.1 changed 'noRandom' tag to 'excludeTheme' and recognize 'excludeLists' tag
2009.09.28 5.4.0 added Check/Init/Reset slices for invoking code during theme switching
2008.04.23 5.3.0 added option for chkRandomTheme (select random theme at startup)
2008.04.13 5.2.0 moved TW2.3.x fixup for core's switchTheme() function to [[SwitchThemePluginPatch]] and simplified random theme handling. Also, changed "Web*" prefix to "*ReadOnly" suffix for compatibility with TW240 core convention.
2008.02.01 5.1.3 in response to a change for core ticket #435 (see http://trac.tiddlywiki.org/changeset/3450) -- in switchTheme, use config.refresherData.* values (if defined), instead of config.refreshers.* This change allows the plugin to work with both the current release (~TW230) AND the upcoming ~TW240 release.
2008.02.01 5.1.2 in switchTheme, replace hard-coded "~StyleSheet" with config.refreshers.stylesheet (used as name of loaded styles)
2008.01.30 5.1.1 changed tag-detection to use "systemTheme" instead of "theme" for compatibility with core theme switching mechanism.
2008.01.26 5.1.0 added support for txtTheme="*" (applies random theme at startup) and {{{<<randomTheme>>}}} macro (selects/applies a random theme when a command link is clicked)
2008.01.25 5.0.1 in refresh() and set(), removed use of ">" to indicate current theme
2008.01.22 5.0.0 Completely re-written and renamed from [[SelectStylesheetPlugin]] (now retired)
>//previous history for [[SelectStylesheetPlugin]] omitted//
2005.07.20 1.0.0 Initial Release
<<<
!usage
{{{[[The Sky's The Limit|The Sky's The Limit]]}}}
[[The Sky's The Limit|The Sky's The Limit]]
!notes
Friday Night Music - live experimental improv - http://www.FridayNightMusic.com
>{{fine{Notice: The recorded material referenced herein is an "original work of art" as defined by United States and California Civil Code, and is protected by copyright. Except for personal non-commercial performance, these works may not be stored, reproduced or re-transmitted in any form without express permission of the rights holders.}}}
''Please do not copy this tiddler.'' This attachment is used by the TiddlyPodPlugin (in the TiddlyPodList playlist tiddler) to virtualize the remote URL reference for this recording. It is intended only as a demonstration for use in the www.TiddlyTools.com on-line document.
!type
audio/mp3
!file
./audio/fnm/001103-4.mp3
!url
http://www.TiddlyTools.com/audio/fnm/001103-4.mp3
!data
{{floatright center fine borderleft{
current theme:
<<switchTheme width:auto>>
|borderless|k
| <<option chkRandomTheme>>| select a random<br>theme at startup |
}}}
This package includes SwitchThemePlugin, which allows you to quickly switch between different system themes (templates and stylesheets). It also includes several pre-defined themes, plus additional stylesheets and 'attachment' tiddlers (using AttachFilePluginFormatters) to support self-contained references for background textures and images.
/***
|Name|TiddlerPasswordPlugin|
|Source|http://www.TiddlyTools.com/#TiddlerPasswordPlugin|
|Documentation|http://www.TiddlyTools.com/#TiddlerPasswordPluginInfo|
|Version|1.1.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|block viewing of tiddler content by prompting for a password before content is displayed|
This plugin blocks viewing of specific tiddler content by prompting for a NON-SECURE, UNENCRYPTED password before the tiddler is displayed. If the correct password is not entered, the tiddler is automatically closed. The process does not prevent tiddler content from being viewed directly from the TiddlyWiki source file's storeArea, nor does it encrypt the tiddler content in any way. Because it is relatively simple to bypass and/or disable the password prompting process, this macro should be thought of as a "latch" rather than a "lock" on a given tiddler.
!!!!!Documentation
> see [[TiddlerPasswordPluginInfo]]
!!!!!Installation Notes
<<<
''As soon as you have installed this plugin, you should change the default admin password in [[TiddlerPasswordPluginConfig]].'' Note: the configuration tiddler is password-protected to prevent the admin password from being viewed (and/or modified) unless the current password is provided. By default, the admin password is set to "admin".
<<<
!!!!!Revisions
<<<
2008.03.10 [*.*.*] plugin size reduction - documentation moved to [[TiddlerPasswordPluginInfo]]
2007.09.13 [1.1.3] adjusted wording of "cancelMsg" text so it can apply to either view-mode or edit-mode activities, and documented usage in ViewTemplate/EditTemplate.
| Please see [[TiddlerPasswordPluginInfo]] for previous revision details |
2006.12.02 [1.0.0] initial release - converted from GetTiddlerPassword inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.TiddlerPasswordPlugin= {major: 1, minor: 1, revision: 3, date: new Date(2007,9,13)};
config.macros.getTiddlerPassword = {
msg: "Please enter a password to view '%0'",
defaultText: "enter password here",
retryMsg: "'%0' is not the correct password for '%1'. Please try again:",
cancelMsg: "Sorry, you cannot access '%0' without a valid password.",
thanksMsg: "Thank you, your password has been accepted.",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var title=tiddler?tiddler.title:here.getAttribute("tiddler");
var who=here.getAttribute("logID");
var userPass=params[0]?params[0]:""; if (userPass=='-') userPass="";
var msg=params[1]?params[1]:this.msg;
if (who==userPass||who==this.adminPass) return; // already 'logged in'?
var who=prompt(msg.format([title]),this.defaultText); // ask for ID
while (who && who!=userPass && who!=this.adminPass) // not correct ID?
who=prompt(this.retryMsg.format([who,title]),this.defaultText); // ask again
if (who==userPass||who==this.adminPass) // correct ID? mark tiddler logged in...
{ here.setAttribute("logID",who); alert(this.thanksMsg); }
else // incorrect ID (e.g., entry cancelled by user)...
{ story.closeTiddler(here.getAttribute("tiddler")); alert(this.cancelMsg.format([title])); }
}
}
// default admin password (may be overridden in TiddlerPasswordPluginConfig)
if (config.macros.getTiddlerPassword.adminPass==undefined)
config.macros.getTiddlerPassword.adminPass="admin";
//}}}
// // Tiddler Admin Password Configuration... <<getTiddlerPassword>> /% rest of tiddler will not be displayed without password... %/
//{{{
config.macros.getTiddlerPassword.adminPass="mypass2";
//}}}
// {{small{NOTE: after changing the password, save-and-reload the document for the change to take effect}}} //
/***
|Name|TiddlerPasswordPlugin|
|Source|http://www.TiddlyTools.com/#TiddlerPasswordPlugin|
|Documentation|http://www.TiddlyTools.com/#TiddlerPasswordPluginInfo|
|Version|1.1.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for TiddlerPasswordPlugin|
This plugin blocks viewing of specific tiddler content by prompting for a NON-SECURE, UNENCRYPTED password before the tiddler is displayed. If the correct password is not entered, the tiddler is automatically closed. The process does not prevent tiddler content from being viewed directly from the TiddlyWiki source file's storeArea, nor does it encrypt the tiddler content in any way. Because it is relatively simple to bypass and/or disable the password prompting process, this macro should be thought of as a "latch" rather than a "lock" on a given tiddler.
!!!!!Usage
<<<
in tiddler content:
>{{{<<getTiddlerPassword>>}}}
>{{{<<getTiddlerPassword password>>}}}
>{{{<<getTiddlerPassword password "prompt message">>}}}
>{{{<<getTiddlerPassword - "prompt message">>}}}
in ViewTemplate or EditTemplate:
>{{{<span macro='getTiddlerPassword ...'></span>}}}
Place the {{{<<getTiddlerPassword>>}}} or {{{<span macro='getTiddlerPassword ...'></span>}}} macro at the beginning of your tiddler content, ViewTemplate and/or EditTemplate. The macro prompts for a password until either A) the correct password is entered or B) the user presses the cancel button from the prompt box, in which case the tiddler is automatically closed so it cannot be viewed/edited. If a valid password is input, it will be remembered only until the user closes the tiddler. Each time the tiddler is opened, the password must be re-entered.
The optional ''password'' parameter provides a "user-level" password for the tiddler in which the macro occurs. If no user password is provided, then only the admin-level password (see below) will be accepted.
By default, the prompt message reads: "Please enter a password to view '%0'" (where the %0 is automatically replaced by the name of the tiddler in which the macro occurs) To change this text, enter an additional macro parameter, following the user password.
>Note: because the prompt text is likely to contain spaces, you should always enclose it in quotes (or use {{{[[...]]}}} if it contains quotes). In addition, to enter an alternative prompt without providing a user-level password, use "-" as a //placeholder// for the password parameter.
* You can set a hard-coded admin password (see below) to define a "universal passkey" that will grant access to all tiddlers protected by this script, regardless of the individual password used on each protected tiddler.
* If you embed one or more password-protected tiddlers within another tiddler (by using the {{{<<tiddler TiddlerName>>}}} macro) the user will be prompted to provide the appropriate password for the EACH protected tiddler contained in the tiddler being rendered.
<<<
!!!!!Installation Notes
<<<
''As soon as you have installed this plugin, you should change the default admin password in [[TiddlerPasswordPluginConfig]].'' Note: the configuration tiddler is password-protected to prevent the admin password from being viewed (and/or modified) unless the current password is provided. By default, the admin password is set to "admin".
<<<
!!!!!Revisions
<<<
2008.03.10 [*.*.*] plugin size reduction - documentation moved to [[TiddlerPasswordPluginInfo]]
2007.09.13 1.1.3 adjusted wording of "cancelMsg" text so it can apply to either view-mode or edit-mode activities, and documented usage in ViewTemplate/EditTemplate.
2007.05.06 1.1.2 changed admin password tiddler name from TiddlerPasswordConfig to TiddlerPasswordPluginConfig so it will be processed AFTER the plugin's default initialization
2007.02.22 1.1.1 updated documentation for using custom prompt text
2007.01.01 1.1.0 added optional param for using custom prompt text
2006.12.03 1.0.1 handler() uses passed-in 'tiddler.title' (if any), so that title of included protected tiddlers can be correctly displayed (instead of showng title of containing tiddler)
2006.12.02 1.0.0 initial release - converted from GetTiddlerPassword inline script
<<<
TiddlyWiki is a core base that enables the portable reuseable non-linear web notebook to work. Please visit the site for your FREE copy @ http://www.TiddlyWiki.com
/***
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 = 'portadoc';
// 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,{
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].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"),
'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"),
'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")
});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 16/11/2010 08:57:29 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . | failed |
| 16/11/2010 08:57:48 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . | failed |
| 16/11/2010 08:58:06 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . |
| 19/11/2010 14:44:23 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/#Home]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . |
| 07/12/2010 08:40:44 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . |
| 07/04/2011 20:22:32 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . | failed |
| 07/04/2011 20:22:54 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . | failed |
| 07/04/2011 20:23:15 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . | failed |
| 07/04/2011 20:23:33 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.tiddlyspot.com/index.html]] | . | failed |
| 07/04/2011 20:24:02 | PortaDoc | [[/|http://portadoc.tiddlyspot.com/]] | [[store.cgi|http://portadoc.tiddlyspot.com/store.cgi]] | . | [[index.html | http://portadoc.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");
//}}}
Would you like to know more?
The following features are included with the standard download of ~TiddlyWiki (this section is not complete):
!Browsers
* You can ''view'' ~TiddlyWiki files on all major desktop browsers on Windows, Macintosh and Linux and many mobile browsers such as the Apple iPhone and the Nokia 770/N800
* You can ''save changes'' to local ~TiddlyWiki files with modern versions of FireFox, Opera, InternetExplorer, Safari, Chrome and Camino
* Community member ~BidiX has created an adaptation of the ~TiddlyWiki user interface [[specially for the iPhone|http://www.apple.com/webapps/productivity/itwatiddlywikiforiphone.html]]
!Tools
* Fully configurable navigation, tagging and searching capability, all using javascript within ~TiddlyWiki itself
* ~TiddlyWiki contains a BackstageArea for handy access to management tools including [[importing|ImportTiddlers]] and [[synchronisation|http://www.tiddlywiki.org/wiki/Dev:Server_Adaptor_Mechanism]] of tiddlers with external files and servers. These tools can also be used to manage a wide range of [[Plugins]] which have been developed by the [[TiddlyWiki community|Help and Support]].
!Content
* Full text formatting including MonospacedText, ExtendedFormatting, NonWikiWordLinks, WikiWordEscape, PrettyLinks, SubHeadings, BulletPoints, NumberedBulletPoints, [[Tables]], BlockQuotes, HorizontalRules and the ability to use a CustomCssClass and InlineHTML
* EmbeddedImages
* [[Macros]] providing rich interactive features, including [[Gradients|GradientMacro]]
!Miscellaneous
* InterfaceOptions and AdvancedOptions, including the ability to GenerateAnRssFeed, SaveBackups and AutoSave
* KeyboardShortcuts so you can finish editing a tiddler with ~Control-Enter or abandon it with Escape
* Extensive StartupParameters to control the behaviour of ~TiddlyWiki through specially crafted ~URLs
* There are [[translations]] of ~TiddlyWiki available in many languages, including Chinese, French, German, Spanish and Portuguese
See also NewFeatures for version <<version>>.
<<getTiddlerPassword>>
password protected?