Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
//only for generate an <<tag Menu>> item
<<tiddler ContactsFormTemplate>>
<<tag Adressebog>>:<<forEachTiddler where 'tiddler.tags.contains("Adressebog")'
sortBy 'tiddler.title'
write
'(index < 200)? "|!"+(index+1)+"|[["+tiddler.title+"]] | "+tiddler.data("phone") +" | "+tiddler.data("mobile") +" | [["+tiddler.data("email")+"|mailto:"+tiddler.data("email")+"]] | [["+tiddler.data("business.email")+"|mailto:"+tiddler.data("business.email")+"]] |\n" : ""'
begin '"|sortable|k\n"
+"|>|>|>|>|>| Alle oprettede |h\n"
+"|!#| !<<wikify %0 title \>\> for | Telefon | Mobil | Mail | ~JobMail |h\n"'
end 'count+" adressekartoteker\n"' none '"Ingen adressekartoteker\n"'>>
/***
|Name|CheckboxPlugin|
|Source|http://www.TiddlyTools.com/#CheckboxPlugin|
|Documentation|http://www.TiddlyTools.com/#CheckboxPluginInfo|
|Version|2.4.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Add checkboxes to your tiddler content|
This plugin extends the TiddlyWiki syntax to allow definition of checkboxes that can be embedded directly in tiddler content. Checkbox states are preserved by:
* by setting/removing tags on specified tiddlers,
* or, by setting custom field values on specified tiddlers,
* or, by saving to a locally-stored cookie ID,
* or, automatically modifying the tiddler content (deprecated)
When an ID is assigned to the checkbox, it enables direct programmatic access to the checkbox DOM element, as well as creating an entry in TiddlyWiki's config.options[ID] internal data. In addition to tracking the checkbox state, you can also specify custom javascript for programmatic initialization and onClick event handling for any checkbox, so you can provide specialized side-effects in response to state changes.
!!!!!Documentation
>see [[CheckboxPluginInfo]]
!!!!!Revisions
<<<
2008.01.08 [*.*.*] plugin size reduction: documentation moved to [[CheckboxPluginInfo]]
2008.01.05 [2.4.0] set global "window.place" to current checkbox element when processing checkbox clicks. This allows init/beforeClick/afterClick handlers to reference RELATIVE elements, including using "story.findContainingTiddler(place)". Also, wrap handlers in "function()" so "return" can be used within handler code.
|please see [[CheckboxPluginInfo]] for additional revision details|
2005.12.07 [0.9.0] initial BETA release
<<<
!!!!!Code
***/
//{{{
version.extensions.CheckboxPlugin = {major: 2, minor: 4, revision:0 , date: new Date(2008,1,5)};
//}}}
//{{{
config.checkbox = { refresh: { tagged:true, tagging:true, container:true } };
config.formatters.push( {
name: "checkbox",
match: "\\[[xX_ ][\\]\\=\\(\\{]",
lookahead: "\\[([xX_ ])(=[^\\s\\(\\]{]+)?(\\([^\\)]*\\))?({[^}]*})?({[^}]*})?({[^}]*})?\\]",
handler: function(w) {
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
// get params
var checked=(lookaheadMatch[1].toUpperCase()=="X");
var id=lookaheadMatch[2];
var target=lookaheadMatch[3];
if (target) target=target.substr(1,target.length-2).trim(); // trim off parentheses
var fn_init=lookaheadMatch[4];
var fn_clickBefore=lookaheadMatch[5];
var fn_clickAfter=lookaheadMatch[6];
var tid=story.findContainingTiddler(w.output); if (tid) tid=tid.getAttribute("tiddler");
var srctid=w.tiddler?w.tiddler.title:null;
config.macros.checkbox.create(w.output,tid,srctid,w.matchStart+1,checked,id,target,config.checkbox.refresh,fn_init,fn_clickBefore,fn_clickAfter);
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
}
} );
config.macros.checkbox = {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
if(!(tiddler instanceof Tiddler)) { // if no tiddler passed in try to find one
var here=story.findContainingTiddler(place);
if (here) tiddler=store.getTiddler(here.getAttribute("tiddler"))
}
var srcpos=0; // "inline X" not applicable to macro syntax
var target=params.shift(); if (!target) target="";
var defaultState=params[0]=="checked"; if (defaultState) params.shift();
var id=params.shift(); if (id && !id.length) id=null;
var fn_init=params.shift(); if (fn_init && !fn_init.length) fn_init=null;
var fn_clickBefore=params.shift();
if (fn_clickBefore && !fn_clickBefore.length) fn_clickBefore=null;
var fn_clickAfter=params.shift();
if (fn_clickAfter && !fn_clickAfter.length) fn_clickAfter=null;
var refresh={ tagged:true, tagging:true, container:false };
this.create(place,tiddler.title,tiddler.title,0,defaultState,id,target,refresh,fn_init,fn_clickBefore,fn_clickAfter);
},
create: function(place,tid,srctid,srcpos,defaultState,id,target,refresh,fn_init,fn_clickBefore,fn_clickAfter) {
// create checkbox element
var c = document.createElement("input");
c.setAttribute("type","checkbox");
c.onclick=this.onClickCheckbox;
c.srctid=srctid; // remember source tiddler
c.srcpos=srcpos; // remember location of "X"
c.container=tid; // containing tiddler (may be null if not in a tiddler)
c.tiddler=tid; // default target tiddler
c.refresh = {};
c.refresh.container = refresh.container;
c.refresh.tagged = refresh.tagged;
c.refresh.tagging = refresh.tagging;
place.appendChild(c);
// set default state
c.checked=defaultState;
// track state in config.options.ID
if (id) {
c.id=id.substr(1); // trim off leading "="
if (config.options[c.id]!=undefined)
c.checked=config.options[c.id];
else
config.options[c.id]=c.checked;
}
// track state in (tiddlername|tagname) or (fieldname@tiddlername)
if (target) {
var pos=target.indexOf("@");
if (pos!=-1) {
c.field=pos?target.substr(0,pos):"checked"; // get fieldname (or use default "checked")
c.tiddler=target.substr(pos+1); // get specified tiddler name (if any)
if (!c.tiddler || !c.tiddler.length) c.tiddler=tid; // if tiddler not specified, default == container
if (store.getValue(c.tiddler,c.field)!=undefined)
c.checked=(store.getValue(c.tiddler,c.field)=="true"); // set checkbox from saved state
} else {
var pos=target.indexOf("|"); if (pos==-1) var pos=target.indexOf(":");
c.tag=target;
if (pos==0) c.tag=target.substr(1); // trim leading "|" or ":"
if (pos>0) { c.tiddler=target.substr(0,pos); c.tag=target.substr(pos+1); }
if (!c.tag.length) c.tag="checked";
var t=store.getTiddler(c.tiddler);
if (t && t.tags)
c.checked=t.isTagged(c.tag); // set checkbox from saved state
}
}
// trim off surrounding { and } delimiters from init/click handlers
if (fn_init) c.fn_init="(function(){"+fn_init.trim().substr(1,fn_init.length-2)+"})()";
if (fn_clickBefore) c.fn_clickBefore="(function(){"+fn_clickBefore.trim().substr(1,fn_clickBefore.length-2)+"})()";
if (fn_clickAfter) c.fn_clickAfter="(function(){"+fn_clickAfter.trim().substr(1,fn_clickAfter.length-2)+"})()";
c.init=true; c.onclick(); c.init=false; // compute initial state and save in tiddler/config/cookie
},
onClickCheckbox: function(event) {
window.place=this;
if (this.init && this.fn_init) // custom function hook to set initial state (run only once)
{ try { eval(this.fn_init); } catch(e) { displayMessage("Checkbox init error: "+e.toString()); } }
if (!this.init && this.fn_clickBefore) // custom function hook to override changes in checkbox state
{ try { eval(this.fn_clickBefore) } catch(e) { displayMessage("Checkbox onClickBefore error: "+e.toString()); } }
if (this.id)
// save state in config AND cookie (only when ID starts with 'chk')
{ config.options[this.id]=this.checked; if (this.id.substr(0,3)=="chk") saveOptionCookie(this.id); }
if (this.srctid && this.srcpos>0 && (!this.id || this.id.substr(0,3)!="chk") && !this.tag && !this.field) {
// save state in tiddler content only if not using cookie, tag or field tracking
var t=store.getTiddler(this.srctid); // put X in original source tiddler (if any)
if (t && this.checked!=(t.text.substr(this.srcpos,1).toUpperCase()=="X")) { // if changed
t.set(null,t.text.substr(0,this.srcpos)+(this.checked?"X":"_")+t.text.substr(this.srcpos+1),null,null,t.tags);
if (!story.isDirty(t.title)) story.refreshTiddler(t.title,null,true);
store.setDirty(true);
}
}
if (this.field) {
if (this.checked && !store.tiddlerExists(this.tiddler))
store.saveTiddler(this.tiddler,this.tiddler,"",config.options.txtUserName,new Date());
// set the field value in the target tiddler
store.setValue(this.tiddler,this.field,this.checked?"true":"false");
// DEBUG: displayMessage(this.field+"@"+this.tiddler+" is "+this.checked);
}
if (this.tag) {
if (this.checked && !store.tiddlerExists(this.tiddler))
store.saveTiddler(this.tiddler,this.tiddler,"",config.options.txtUserName,new Date());
var t=store.getTiddler(this.tiddler);
if (t) {
var tagged=(t.tags && t.tags.indexOf(this.tag)!=-1);
if (this.checked && !tagged) { t.tags.push(this.tag); store.setDirty(true); }
if (!this.checked && tagged) { t.tags.splice(t.tags.indexOf(this.tag),1); store.setDirty(true); }
}
// if tag state has been changed, update display of corresponding tiddlers (unless they are in edit mode...)
if (this.checked!=tagged) {
if (this.refresh.tagged) {
if (!story.isDirty(this.tiddler)) // the TAGGED tiddler in view mode
story.refreshTiddler(this.tiddler,null,true);
else // the TAGGED tiddler in edit mode (with tags field)
config.macros.checkbox.refreshEditorTagField(this.tiddler,this.tag,this.checked);
}
if (this.refresh.tagging)
if (!story.isDirty(this.tag)) story.refreshTiddler(this.tag,null,true); // the TAGGING tiddler
}
}
if (!this.init && this.fn_clickAfter) // custom function hook to react to changes in checkbox state
{ try { eval(this.fn_clickAfter) } catch(e) { displayMessage("Checkbox onClickAfter error: "+e.toString()); } }
// refresh containing tiddler (but not during initial rendering, or we get an infinite loop!) (and not when editing container)
if (!this.init && this.refresh.container && this.container!=this.tiddler)
if (!story.isDirty(this.container)) story.refreshTiddler(this.container,null,true); // the tiddler CONTAINING the checkbox
return true;
},
refreshEditorTagField: function(title,tag,set) {
var tagfield=story.getTiddlerField(title,"tags");
if (!tagfield||tagfield.getAttribute("edit")!="tags") return; // if no tags field in editor (i.e., custom template)
var tags=tagfield.value.readBracketedList();
if (tags.contains(tag)==set) return; // if no change needed
if (set) tags.push(tag); // add tag
else tags.splice(tags.indexOf(tag),1); // remove tag
for (var t=0;t<tags.length;t++) tags[t]=String.encodeTiddlyLink(tags[t]);
tagfield.value=tags.join(" "); // reassemble tag string (with brackets as needed)
return;
}
}
//}}}
<<search>>
----
<<newTiddler title:"ElevNavn" label:"New Student" tag:"Elev">>
<<newTiddler title:"LærerInitialer" label:"New Teacher" tag:"Lærere">>
<<newTiddler>>
<<saveChanges>>
----
[[Lister]]
<<forEachTiddler where 'tiddler.tags.contains("Lærere") && tiddler.fields["fuldenavn"] && tiddler.fields["fuldenavn"].contains(context.viewerTiddler.title)'>><html>
<style>
.rolodex table {
border: 0px solid;
}
.rolodex tr, .rolodex td {
border: 0px solid;
}
</style>
</html>
<<tabs addressBookTabs
Overblik "Navn, Email, hjemmeside URL, etc." TwabTabParts/tab1form
Hjem "Hjemme adresse/telefonnr, etc." TwabTabParts/tab2form
Job "Alternativ kontaktadresse/telefonnr, etc." TwabTabParts/tab3form
Andet "Noter, fødselsdag, Cpr, etc." TwabTabParts/tab4form
>><<tiddler RefreshTiddler with: "Opfrisk" "Genopfrisk visning">> <<tiddler AdresseBogUpdate>>
/***
|''Name:''|DataTiddlerPlugin|
|''Version:''|1.0.6 (2006-08-26)|
|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).
Such tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers.
''//Example: "Table with all December Expenses"//''
{{{
<<forEachTiddler
where
'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
write
'"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
}}}
//(This assumes that expenses are stored in tiddlers tagged with "expense".)//
<<forEachTiddler
where
'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
write
'"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
For other examples see DataTiddlerExamples.
''Access and Modify Tiddler Data''
You can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields.
These values can be accessed and modified through the following Tiddler methods:
|!Method|!Example|!Description|
|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
Alternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.
|!Method|!Description|
|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
//(For details on the various functions see the detailed comments in the source code.)//
''Data Representation in a Tiddler''
The data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]].
//''Data Section Example:''//
{{{
<data>{"isVIP":true,"user":"John Brown","age":34}</data>
}}}
The data section is not displayed when viewing the tiddler (see also "The showData Macro").
Beside the data section a tiddler may have all kind of other content.
Typically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.
''Saving Changes''
The "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.
''Notifications''
No notifications are sent when a tiddler's data value is changed through the "setData" methods.
''Escape Data Section''
In case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.
''The showData Macro''
By default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:
''Syntax:''
|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|
|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|
|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
!Revision history
* v1.0.6 (2006-08-26)
** Removed misleading comment
* v1.0.5 (2006-02-27) (Internal Release Only)
** Internal
*** Make "JSLint" conform
* v1.0.4 (2006-02-05)
** Bugfix: showData fails in TiddlyWiki 2.0
* v1.0.3 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.2 (2005-12-22)
** Enhancements:
*** Handle texts "<data>" or "</data>" more robust when used in a tiddler text or as a field value.
*** Improved (JSON) error messages.
** Bugs fixed:
*** References are not updated when using the DataTiddler.
*** Changes to compound objects are not always saved.
*** "~</data>" is not rendered correctly (expected "</data>")
* v1.0.1 (2005-12-13)
** Features:
*** The showData macro supports an optional "tiddlername" argument to specify the tiddler containing the data to be displayed
** Bugs fixed:
*** A script immediately following a data section is deleted when the data is changed. (Thanks to GeoffS for reporting.)
* v1.0.0 (2005-12-12)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// DataTiddlerPlugin
//============================================================================
//============================================================================
// Ensure that the DataTiddler Plugin is only installed once.
//
if (!version.extensions.DataTiddlerPlugin) {
version.extensions.DataTiddlerPlugin = {
major: 1, minor: 0, revision: 6,
date: new Date(2006, 7, 26),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"
};
// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window;
if (!TiddlyWiki.prototype.getTiddler) {
TiddlyWiki.prototype.getTiddler = function(title) {
var t = this.tiddlers[title];
return (t !== undefined && t instanceof Tiddler) ? t : null;
};
}
//============================================================================
// DataTiddler Class
//============================================================================
// ---------------------------------------------------------------------------
// Configurations and constants
// ---------------------------------------------------------------------------
function DataTiddler() {
}
DataTiddler = {
// Function to stringify a JavaScript value, producing the text for the data section content.
// (Must match the implementation of DataTiddler.parse.)
//
stringify : null,
// Function to parse the text for the data section content, producing a JavaScript value.
// (Must match the implementation of DataTiddler.stringify.)
//
parse : null
};
// Ensure access for IE
window.DataTiddler = DataTiddler;
// ---------------------------------------------------------------------------
// Data Accessor and Mutator
// ---------------------------------------------------------------------------
// Returns the value of the given data field of the tiddler.
// When no such field is defined or its value is undefined
// the defaultValue is returned.
//
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.getData = function(tiddler, field, defaultValue) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.getTiddlerDataValue(t, field, defaultValue);
};
// Sets the value of the given data field of the tiddler to
// the value. When the value is equal to the defaultValue
// no value is set (and the field is removed)
//
// Changing data of a tiddler will not trigger notifications.
//
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.setData = function(tiddler, field, value, defaultValue) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler+ "("+t+")";
}
DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);
};
// Returns the data object of the tiddler, with a property for every field.
//
// The properties of the returned data object may only be read and
// not be modified. To modify the data use DataTiddler.setData(...)
// or the corresponding Tiddler method.
//
// If no data section is defined a new (empty) object is returned.
//
// @param tiddler either a tiddler name or a Tiddler
//
DataTiddler.getDataObject = function(tiddler) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.getTiddlerDataObject(t);
};
// Returns the text of the content of the data section of the tiddler.
//
// When no data section is defined for the tiddler null is returned
//
// @param tiddler either a tiddler name or a Tiddler
// @return [may be null]
//
DataTiddler.getDataText = function(tiddler) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.readDataSectionText(t);
};
// ---------------------------------------------------------------------------
// Internal helper methods (must not be used by code from outside this plugin)
// ---------------------------------------------------------------------------
// Internal.
//
// The original JSONError is not very user friendly,
// especially it does not define a toString() method
// Therefore we extend it here.
//
DataTiddler.extendJSONError = function(ex) {
if (ex.name == 'JSONError') {
ex.toString = function() {
return ex.name + ": "+ex.message+" ("+ex.text+")";
};
}
return ex;
};
// Internal.
//
// @param t a Tiddler
//
DataTiddler.getTiddlerDataObject = function(t) {
if (t.dataObject === undefined) {
var data = DataTiddler.readData(t);
t.dataObject = (data) ? data : {};
}
return t.dataObject;
};
// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {
var value = DataTiddler.getTiddlerDataObject(tiddler)[field];
return (value === undefined) ? defaultValue : value;
};
// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {
var data = DataTiddler.getTiddlerDataObject(tiddler);
var oldValue = data[field];
if (value == defaultValue) {
if (oldValue !== undefined) {
delete data[field];
DataTiddler.save(tiddler);
}
return;
}
data[field] = value;
DataTiddler.save(tiddler);
};
// Internal.
//
// Reads the data section from the tiddler's content and returns its text
// (as a String).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readDataSectionText = function(tiddler) {
var matches = DataTiddler.getDataTiddlerMatches(tiddler);
if (matches === null || !matches[2]) {
return null;
}
return matches[2];
};
// Internal.
//
// Reads the data section from the tiddler's content and returns it
// (as an internalized object).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readData = function(tiddler) {
var text = DataTiddler.readDataSectionText(tiddler);
try {
return text ? DataTiddler.parse(text) : null;
} catch(ex) {
throw DataTiddler.extendJSONError(ex);
}
};
// Internal.
//
// Returns the serialized text of the data of the given tiddler, as it
// should be stored in the data section.
//
// @param tiddler a Tiddler
//
DataTiddler.getDataTextOfTiddler = function(tiddler) {
var data = DataTiddler.getTiddlerDataObject(tiddler);
return DataTiddler.stringify(data);
};
// Internal.
//
DataTiddler.indexOfNonEscapedText = function(s, subString, startIndex) {
var index = s.indexOf(subString, startIndex);
while ((index > 0) && (s[index-1] == '~')) {
index = s.indexOf(subString, index+1);
}
return index;
};
// Internal.
//
DataTiddler.getDataSectionInfo = function(text) {
// Special care must be taken to handle "<data>" and "</data>" texts inside
// a data section.
// Also take care not to use an escaped <data> (i.e. "~<data>") as the start
// of a data section. (Same for </data>)
// NOTE: we are explicitly searching for a data section that contains a JSON
// string, i.e. framed with braces. This way we are little bit more robust in
// case the tiddler contains unescaped texts "<data>" or "</data>". This must
// be changed when using a different stringifier.
var startTagText = "<data>{";
var endTagText = "}</data>";
var startPos = 0;
// Find the first not escaped "<data>".
var startDataTagIndex = DataTiddler.indexOfNonEscapedText(text, startTagText, 0);
if (startDataTagIndex < 0) {
return null;
}
// Find the *last* not escaped "</data>".
var endDataTagIndex = text.indexOf(endTagText, startDataTagIndex);
if (endDataTagIndex < 0) {
return null;
}
var nextEndDataTagIndex;
while ((nextEndDataTagIndex = text.indexOf(endTagText, endDataTagIndex+1)) >= 0) {
endDataTagIndex = nextEndDataTagIndex;
}
return {
prefixEnd: startDataTagIndex,
dataStart: startDataTagIndex+(startTagText.length)-1,
dataEnd: endDataTagIndex,
suffixStart: endDataTagIndex+(endTagText.length)
};
};
// Internal.
//
// Returns the "matches" of a content of a DataTiddler on the
// "data" regular expression. Return null when no data is defined
// in the tiddler content.
//
// Group 1: text before data section (prefix)
// Group 2: content of data section
// Group 3: text behind data section (suffix)
//
// @param tiddler a Tiddler
// @return [may be null] null when the tiddler contains no data section, otherwise see above.
//
DataTiddler.getDataTiddlerMatches = function(tiddler) {
var text = tiddler.text;
var info = DataTiddler.getDataSectionInfo(text);
if (!info) {
return null;
}
var prefix = text.substr(0,info.prefixEnd);
var data = text.substr(info.dataStart, info.dataEnd-info.dataStart+1);
var suffix = text.substr(info.suffixStart);
return [text, prefix, data, suffix];
};
// Internal.
//
// Saves the data in a <data> block of the given tiddler (as a minor change).
//
// The "chkAutoSave" and "chkForceMinorUpdate" options are respected.
// I.e. the TiddlyWiki *file* is only saved when AutoSave is on.
//
// Notifications are not send.
//
// This method should only be called when the data really has changed.
//
// @param tiddler
// the tiddler to be saved.
//
DataTiddler.save = function(tiddler) {
var matches = DataTiddler.getDataTiddlerMatches(tiddler);
var prefix;
var suffix;
if (matches === null) {
prefix = tiddler.text;
suffix = "";
} else {
prefix = matches[1];
suffix = matches[3];
}
var dataText = DataTiddler.getDataTextOfTiddler(tiddler);
var newText =
(dataText !== null)
? prefix + "<data>" + dataText + "</data>" + suffix
: prefix + suffix;
if (newText != tiddler.text) {
// make the change in the tiddlers text
// ... see DataTiddler.MyTiddlerChangedFunction
tiddler.isDataTiddlerChange = true;
// ... do the action change
tiddler.set(
tiddler.title,
newText,
config.options.txtUserName,
config.options.chkForceMinorUpdate? undefined : new Date(),
tiddler.tags);
// ... see DataTiddler.MyTiddlerChangedFunction
delete tiddler.isDataTiddlerChange;
// Mark the store as dirty.
store.dirty = true;
// AutoSave if option is selected
if(config.options.chkAutoSave) {
saveChanges();
}
}
};
// Internal.
//
DataTiddler.MyTiddlerChangedFunction = function() {
// Remove the data object from the tiddler when the tiddler is changed
// by code other than DataTiddler code.
//
// This is necessary since the data object is just a "cached version"
// of the data defined in the data section of the tiddler and the
// "external" change may have changed the content of the data section.
// Thus we are not sure if the data object reflects the data section
// contents.
//
// By deleting the data object we ensure that the data object is
// reconstructed the next time it is needed, with the data defined by
// the data section in the tiddler's text.
// To indicate that a change is a "DataTiddler change" a temporary
// property "isDataTiddlerChange" is added to the tiddler.
if (this.dataObject && !this.isDataTiddlerChange) {
delete this.dataObject;
}
// call the original code.
DataTiddler.originalTiddlerChangedFunction.apply(this, arguments);
};
//============================================================================
// Formatters
//============================================================================
// This formatter ensures that "~<data>" is rendered as "<data>". This is used to
// escape the "<data>" of a data section, just in case someone really wants to use
// "<data>" as a text in a tiddler and not start a data section.
//
// Same for </data>.
//
config.formatters.push( {
name: "data-escape",
match: "~<\\/?data>",
handler: function(w) {
w.outputText(w.output,w.matchStart + 1,w.nextMatch);
}
} );
// This formatter ensures that <data>...</data> sections are not rendered.
//
config.formatters.push( {
name: "data",
match: "<data>",
handler: function(w) {
var info = DataTiddler.getDataSectionInfo(w.source);
if (info && info.prefixEnd == w.matchStart) {
w.nextMatch = info.suffixStart;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
}
} );
//============================================================================
// Tiddler Class Extension
//============================================================================
// "Hijack" the changed method ---------------------------------------------------
DataTiddler.originalTiddlerChangedFunction = Tiddler.prototype.changed;
Tiddler.prototype.changed = DataTiddler.MyTiddlerChangedFunction;
// Define accessor methods -------------------------------------------------------
// Returns the value of the given data field of the tiddler. When no such field
// is defined or its value is undefined the defaultValue is returned.
//
// When field is undefined (or null) the data object is returned. (See
// DataTiddler.getDataObject.)
//
// @param field [may be null, undefined]
// @param defaultValue [may be null, undefined]
// @return [may be null, undefined]
//
Tiddler.prototype.data = function(field, defaultValue) {
return (field)
? DataTiddler.getTiddlerDataValue(this, field, defaultValue)
: DataTiddler.getTiddlerDataObject(this);
};
// Sets the value of the given data field of the tiddler to the value. When the
// value is equal to the defaultValue no value is set (and the field is removed).
//
// @param value [may be null, undefined]
// @param defaultValue [may be null, undefined]
//
Tiddler.prototype.setData = function(field, value, defaultValue) {
DataTiddler.setTiddlerDataValue(this, field, value, defaultValue);
};
//============================================================================
// showData Macro
//============================================================================
config.macros.showData = {
// Standard Properties
label: "showData",
prompt: "Display the values stored in the data section of the tiddler"
};
config.macros.showData.handler = function(place,macroName,params) {
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// Parse the optional "JSON"
var showInJSONFormat = false;
if ((i < params.length) && params[i] == "JSON") {
i++;
showInJSONFormat = true;
}
var tiddlerName = story.findContainingTiddler(place).id.substr(7);
if (i < params.length) {
tiddlerName = params[i];
i++;
}
// --- Processing ------------------------------------------
try {
if (showInJSONFormat) {
this.renderDataInJSONFormat(place, tiddlerName);
} else {
this.renderDataAsTable(place, tiddlerName);
}
} catch (e) {
this.createErrorElement(place, e);
}
};
config.macros.showData.renderDataInJSONFormat = function(place,tiddlerName) {
var text = DataTiddler.getDataText(tiddlerName);
if (text) {
createTiddlyElement(place,"pre",null,null,text);
}
};
config.macros.showData.renderDataAsTable = function(place,tiddlerName) {
var text = "|!Name|!Value|\n";
var data = DataTiddler.getDataObject(tiddlerName);
if (data) {
for (var i in data) {
var value = data[i];
text += "|"+i+"|"+DataTiddler.stringify(value)+"|\n";
}
}
wikify(text, place);
};
// Internal.
//
// Creates an element that holds an error message
//
config.macros.showData.createErrorElement = function(place, exception) {
var message = (exception.description) ? exception.description : exception.toString();
return createTiddlyElement(place,"span",null,"showDataError","<<showData ...>>: "+message);
};
// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
".showDataError{color: #ffffff;background-color: #880000;}",
"showData");
} // of "install only once"
// Used Globals (for JSLint) ==============
// ... TiddlyWiki Core
/*global createTiddlyElement, saveChanges, store, story, wikify */
// ... DataTiddler
/*global DataTiddler */
// ... JSON
/*global JSON */
/***
!JSON Code, used to serialize the data
***/
/*
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
The global object JSON contains two methods.
JSON.stringify(value) takes a JavaScript value and produces a JSON text.
The value must not be cyclical.
JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
throw a 'JSONError' exception if there is an error.
*/
var JSON = {
copyright: '(c)2005 JSON.org',
license: 'http://www.crockford.com/JSON/license.html',
/*
Stringify a JavaScript value, producing a JSON text.
*/
stringify: function (v) {
var a = [];
/*
Emit a string.
*/
function e(s) {
a[a.length] = s;
}
/*
Convert a value.
*/
function g(x) {
var c, i, l, v;
switch (typeof x) {
case 'object':
if (x) {
if (x instanceof Array) {
e('[');
l = a.length;
for (i = 0; i < x.length; i += 1) {
v = x[i];
if (typeof v != 'undefined' &&
typeof v != 'function') {
if (l < a.length) {
e(',');
}
g(v);
}
}
e(']');
return;
} else if (typeof x.toString != 'undefined') {
e('{');
l = a.length;
for (i in x) {
v = x[i];
if (x.hasOwnProperty(i) &&
typeof v != 'undefined' &&
typeof v != 'function') {
if (l < a.length) {
e(',');
}
g(i);
e(':');
g(v);
}
}
return e('}');
}
}
e('null');
return;
case 'number':
e(isFinite(x) ? +x : 'null');
return;
case 'string':
l = x.length;
e('"');
for (i = 0; i < l; i += 1) {
c = x.charAt(i);
if (c >= ' ') {
if (c == '\\' || c == '"') {
e('\\');
}
e(c);
} else {
switch (c) {
case '\b':
e('\\b');
break;
case '\f':
e('\\f');
break;
case '\n':
e('\\n');
break;
case '\r':
e('\\r');
break;
case '\t':
e('\\t');
break;
default:
c = c.charCodeAt();
e('\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16));
}
}
}
e('"');
return;
case 'boolean':
e(String(x));
return;
default:
e('null');
return;
}
}
g(v);
return a.join('');
},
/*
Parse a JSON text, producing a JavaScript value.
*/
parse: function (text) {
var p = /^\s*(([,:{}\[\]])|"(\\.|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)\s*/,
token,
operator;
function error(m, t) {
throw {
name: 'JSONError',
message: m,
text: t || operator || token
};
}
function next(b) {
if (b && b != operator) {
error("Expected '" + b + "'");
}
if (text) {
var t = p.exec(text);
if (t) {
if (t[2]) {
token = null;
operator = t[2];
} else {
operator = null;
try {
token = eval(t[1]);
} catch (e) {
error("Bad token", t[1]);
}
}
text = text.substring(t[0].length);
} else {
error("Unrecognized token", text);
}
} else {
token = operator = undefined;
}
}
function val() {
var k, o;
switch (operator) {
case '{':
next('{');
o = {};
if (operator != '}') {
for (;;) {
if (operator || typeof token != 'string') {
error("Missing key");
}
k = token;
next();
next(':');
o[k] = val();
if (operator != ',') {
break;
}
next(',');
}
}
next('}');
return o;
case '[':
next('[');
o = [];
if (operator != ']') {
for (;;) {
o.push(val());
if (operator != ',') {
break;
}
next(',');
}
}
next(']');
return o;
default:
if (operator !== null) {
error("Missing value");
}
k = token;
next();
return k;
}
}
next();
return val();
}
};
/***
!Setup the data serialization
***/
DataTiddler.format = "JSON";
DataTiddler.stringify = JSON.stringify;
DataTiddler.parse = JSON.parse;
//}}}
<div class='toolbar' macro='toolbar +saveTiddler closeOthers -cancelTiddler deleteTiddler wikibar'></div>
<div class='title' macro='view title'></div>
<div class='editLabel'>Title</div><div class='editor' macro='edit title'></div>
<div class='editLabel'>Tags</div><div class='editor' macro='edit tags'></div>
<div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<div macro='hideWhen ((tiddler.tags.contains("Contacts"))||(tiddler.title=="New Contact"))'>[[EditToolbar]]<div class='editor' macro='edit text'></div></div>
<div macro='showWhen ((tiddler.tags.contains("Contacts"))||(tiddler.title=="New Contact"))'><div class='editor'>
<table width='100%'>
<tbody><tr><th>Name</th><td><span macro='edit ContactFirstName'></span><span macro='edit ContactLastName'></span></td><td rowspan='4' macro='edit text' width='50%'></td></tr>
<tr><th>Adress</th><td><span macro='edit ContactStreetNumber'></span><span macro='edit ContactStreetName'></span><span macro='edit ContactZipCode'></span><span macro='edit ContactCity'></span></td></tr>
<tr><th>Phone</th><td><span macro='edit ContactPhone'></span></td></tr>
<tr><th>Email</th><td><span macro='edit ContactMail'><span></span></span></td></tr>
</tbody></table>
</div></div>
Elever på HU
<<forEachTiddler
where
'tiddler.tags.contains("Elev")'
sortBy 'tiddler.title'
write
'(index < 200) ? "|!"+(index+1)+"|[["+tiddler.title+"]]|"+tiddler.body+"|"+tiddler.tags+"|[["+tiddler.fields["k-gruppe"]+"]]|[["+tiddler.fields["gang"]+"]]|[["+tiddler.fields["kl"]+"]]|[["+tiddler.fields["værelse"]+"]]|"+tiddler.fields["billede"] +"|\n" : ""'
begin '"|sortable|k\n|!#|title|text|tags|k-gruppe|gang|kl|værelse|billede|h\n"'
end 'count+" elever\n"'
none '"Ingen elever\n"'
>>
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='toolbar' macro='toolbar +saveTiddler closeOthers -cancelTiddler deleteTiddler wikibar'></div>
<div style='clear:both'></div>
<div class='viewer'>
<table class='borderless' style='width:100%'><tr>
<td style='width:10%'>
<div class='small'>Gang:</div>
<div class='editor' macro='select gang rows:1 width:75% allowBlank allowOther +GangListe allowEdit'></div>
<div class='small'>K-gruppe:</div>
<div class='editor' macro='select k-gruppe rows:1 width:75% allowBlank allowOther +LærerListe allowEdit'></div>
<div class='small'>Klasse:</div>
<div class='editor' macro='select kl rows:1 width:75% allowBlank allowOther 9 10 '></div>
<div class='small'>Værelse:</div>
<div class='editor' macro='select værelse rows:1 width:75% allowBlank allowOther +Værelser allowEdit'></div>
</td><td style='width:20%'>
<div class='small'>ElevNavn (tiddler navn):</div>
<div class='editor' macro='edit title'></div>
<div class='small'>Email:</div>
<div class='editor' macro='select email rows:1 width:100% allowBlank allowOther +EmailListe allowEdit'></div>
<div class='small'>billede URL (jpg/gif):</div>
<div class='editor' macro='edit billede'></div>
</td></table>
<div class='small borderless'><span class='small'>Note (Besked:):</span></div>
<div class='editor' macro='edit text 10'></div>
<div class='editor' macro='edit tags'></div>
<div class='toolbar editorFooter' style='text-align:left !important;float:left !important'>
<span macro='message views.editor.tagPrompt'></span><span class macro='newTiddler label: sAdressebog title:{{tiddler.title+"-"}} tag: {{tiddler.title}} Adressebog text: {{store.getTiddlerText("AdresseTabs")}} ' </span>
<span macro='tagChooser'></span>
</div>
<div style='clear:both'></div>
</div><!-- viewer -->
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ElevViewToolbar]]'>
<span macro='email to:{{tiddler.fields.email}} permalink:"true"'></span>
</div>
<div class='title' macro='view title'></div>
<span class macro='newJournalHere label:SygDD tag:"NoteArkiv" text:"Skriv sygenotater her"'></span>
<span class macro="tiddler SaveThisTiddler"></span>
<span class='subtitle' style='white-space:nowrap' macro='view modified date [[DDD, DDe MMM YYYY]]'></span>
<div macro="hideWhenTaggedAny systemTool systemList">
<div class='tagged' macro='tags'></div>
</div>
<div class='tagClear'></div>
<div class='menubox' style='float:center;margin:0em'>
<span macro="toggleTag Syg . -"></span>
<span macro="tag Syg "></span>
<span macro="checkbox mad@"></span>
Mad<span macro="checkbox seng@"></span>
Seng<span macro="toggleTag HU . -"></span>
<span macro="tag HU "></span>
<span macro="checkbox andet@"></span>
Andet<span macro="checkbox hjem@""></span>
Hjem
</div>
<div class='viewer'></div>
<div class macro='wikify [img[%1|%0][%1-]] billede@here title@here'></div>
<span macro='tag Lærere K-gruppe:'></span>
<span macro='wikify "[[%0]]" k-gruppe'></span>
<span macro='tag Kl Klasse:'></span>
<span macro='wikify "[[%0]]" kl'></span>
<span macro='tag GangOversigt Gang:'></span>
<span macro='wikify "[[%0]]" gang'></span>
<span macro='tag Værelser Vær.:'></span>
<span macro='wikify "%0" værelse'></span>
<span macro='wikify "//@@bgcolor(#99ff33):Besked:@@//"'></span>
<span macro='wikify "@@color(#cc0000): %0@@" text'></span>
<div class='tagClear'></div>
<!--}}}-->
/***
|''Name:''|FieldsEditorPlugin|
|''Description:''|//create//, //edit//, //view// and //delete// commands in toolbar <<toolbar fields>>.|
|''Version:''|1.0.2|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demo:
On [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], see [[FieldEditor example]]
!Installation:
*import this tiddler from [[homepage|http://visualtw.ouvaton.org/VisualTW.html]] (tagged as systemConfig)
*save and reload
*optionnaly : add the following css text in your StyleSheet : {{{#popup tr.fieldTableRow td {padding:1px 3px 1px 3px;}}}}
!Code
***/
//{{{
config.commands.fields.handlePopup = function(popup,title) {
var tiddler = store.fetchTiddler(title);
if(!tiddler)
return;
var fields = {};
store.forEachField(tiddler,function(tiddler,fieldName,value) {fields[fieldName] = value;},true);
var items = [];
for(var t in fields) {
var editCommand = "<<untiddledCall editFieldDialog "+escape(title)+" "+escape(t)+">>";
var deleteCommand = "<<untiddledCall deleteField "+escape(title)+" "+escape(t)+">>";
var renameCommand = "<<untiddledCall renameField "+escape(title)+" "+escape(t)+">>";
items.push({field: t,value: fields[t], actions: editCommand+renameCommand+deleteCommand});
}
items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
var createNewCommand = "<<untiddledCall createField "+escape(title)+">>";
items.push({field : "", value : "", actions:createNewCommand });
if(items.length > 0)
ListView.create(popup,items,this.listViewTemplate);
else
createTiddlyElement(popup,"div",null,null,this.emptyText);
}
config.commands.fields.listViewTemplate = {
columns: [
{name: 'Field', field: 'field', title: "Field", type: 'String'},
{name: 'Actions', field: 'actions', title: "Actions", type: 'WikiText'},
{name: 'Value', field: 'value', title: "Value", type: 'WikiText'}
],
rowClasses: [
{className: 'fieldTableRow', field: 'actions'}
],
buttons: [ //can't use button for selected then delete, because click on checkbox will hide the popup
]
}
config.macros.untiddledCall = { // when called from listview, tiddler is unset, so we need to pass tiddler as parameter
handler : function(place,macroName,params,wikifier,paramString) {
var macroName = params.shift();
if (macroName) var macro = config.macros[macroName];
var title = params.shift();
if (title) var tiddler = store.getTiddler(unescape(title));
if (macro) macro.handler(place,macroName,params,wikifier,paramString,tiddler);
}
}
config.macros.deleteField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"delete", "delete "+fieldName,this.onClickDeleteField);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickDeleteField : function() {
var title=this.getAttribute("title");
var fieldName=this.getAttribute("fieldName");
var tiddler = store.getTiddler(title);
if (tiddler && fieldName && confirm("delete field " + fieldName+" from " + title +" tiddler ?")) {
delete tiddler.fields[fieldName];
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
return false;
}
}
config.macros.createField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly) {
var btn = createTiddlyButton(place,"create new", "create a new field",this.onClickCreateField);
btn.setAttribute("title",tiddler.title);
}
},
onClickCreateField : function() {
var title=this.getAttribute("title");
var tiddler = store.getTiddler(title);
if (tiddler) {
var fieldName = prompt("Field name","");
if (store.getValue(tiddler,fieldName)) {
window.alert("This field already exists.");
}
else if (fieldName) {
var v = prompt("Field value","");
tiddler.fields[fieldName]=v;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.macros.editFieldDialog = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"edit", "edit this field",this.onClickEditFieldDialog);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickEditFieldDialog : function() {
var title=this.getAttribute("title");
var tiddler = store.getTiddler(title);
var fieldName=this.getAttribute("fieldName");
if (tiddler && fieldName) {
var value = tiddler.fields[fieldName];
value = value ? value : "";
var lines = value.match(/n/mg);
lines = lines ? true : false;
if (!lines || confirm("This field contains more than one line. Only the first line will be kept if you edit it here. Proceed ?")) {
var v = prompt("Field value",value);
tiddler.fields[fieldName]=v;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.macros.renameField = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if(!readOnly && params[0]) {
fieldName = unescape(params[0]);
var btn = createTiddlyButton(place,"rename", "rename "+fieldName,this.onClickRenameField);
btn.setAttribute("title",tiddler.title);
btn.setAttribute("fieldName", fieldName);
}
},
onClickRenameField : function() {
var title=this.getAttribute("title");
var fieldName=this.getAttribute("fieldName");
var tiddler = store.getTiddler(title);
if (tiddler && fieldName) {
var newName = prompt("Rename " + fieldName + " as ?", fieldName);
if (newName) {
tiddler.fields[newName]=tiddler.fields[fieldName];
delete tiddler.fields[fieldName];
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(title,"ViewTemplate",true);
}
}
return false;
}
}
config.shadowTiddlers.StyleSheetFieldsEditor = "/*{{{*/n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow td {padding : 1px 3px}n";
config.shadowTiddlers.StyleSheetFieldsEditor += ".fieldTableRow .button {border:0; padding : 0 0.2em}n";
config.shadowTiddlers.StyleSheetFieldsEditor +="/*}}}*/";
store.addNotification("StyleSheetFieldsEditor", refreshStyles);
//}}}
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|© 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description
Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.
''Syntax:''
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].
!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features:
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen)
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features:
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs:
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features:
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// ForEachTiddlerPlugin
//============================================================================
//============================================================================
// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {
if (!window.abego) window.abego = {};
version.extensions.ForEachTiddlerPlugin = {
major: 1, minor: 0, revision: 8,
date: new Date(2007,3,12),
source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};
// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
TiddlyWiki.prototype.forEachTiddler = function(callback) {
for(var t in this.tiddlers) {
callback.call(this,t,this.tiddlers[t]);
}
};
}
//============================================================================
// forEachTiddler Macro
//============================================================================
version.extensions.forEachTiddler = {
major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};
// ---------------------------------------------------------------------------
// Configurations and constants
// ---------------------------------------------------------------------------
config.macros.forEachTiddler = {
// Standard Properties
label: "forEachTiddler",
prompt: "Perform actions on a (sorted) selection of tiddlers",
// actions
actions: {
addToList: {},
write: {}
}
};
// ---------------------------------------------------------------------------
// The forEachTiddler Macro Handler
// ---------------------------------------------------------------------------
config.macros.forEachTiddler.getContainingTiddler = function(e) {
while(e && !hasClass(e,"tiddler"))
e = e.parentNode;
var title = e ? e.getAttribute("tiddler") : null;
return title ? store.getTiddler(title) : null;
};
config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);
if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// Parse the "in" clause
var tiddlyWikiPath = undefined;
if ((i < params.length) && params[i] == "in") {
i++;
if (i >= params.length) {
this.handleError(place, "TiddlyWiki path expected behind 'in'.");
return;
}
tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the where clause
var whereClause ="true";
if ((i < params.length) && params[i] == "where") {
i++;
whereClause = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the sort stuff
var sortClause = null;
var sortAscending = true;
if ((i < params.length) && params[i] == "sortBy") {
i++;
if (i >= params.length) {
this.handleError(place, "sortClause missing behind 'sortBy'.");
return;
}
sortClause = this.paramEncode(params[i]);
i++;
if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
sortAscending = params[i] == "ascending";
i++;
}
}
// Parse the script
var scriptText = null;
if ((i < params.length) && params[i] == "script") {
i++;
scriptText = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the action.
// When we are already at the end use the default action
var actionName = "addToList";
if (i < params.length) {
if (!config.macros.forEachTiddler.actions[params[i]]) {
this.handleError(place, "Unknown action '"+params[i]+"'.");
return;
} else {
actionName = params[i];
i++;
}
}
// Get the action parameter
// (the parsing is done inside the individual action implementation.)
var actionParameter = params.slice(i);
// --- Processing ------------------------------------------
try {
this.performMacro({
place: place,
inTiddler: tiddler,
whereClause: whereClause,
sortClause: sortClause,
sortAscending: sortAscending,
actionName: actionName,
actionParameter: actionParameter,
scriptText: scriptText,
tiddlyWikiPath: tiddlyWikiPath});
} catch (e) {
this.handleError(place, e);
}
};
// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {
var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);
var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
context["tiddlyWiki"] = tiddlyWiki;
// Get the tiddlers, as defined by the whereClause
var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
context["tiddlers"] = tiddlers;
// Sort the tiddlers, when sorting is required.
if (parameter.sortClause) {
this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
}
return {tiddlers: tiddlers, context: context};
};
// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
return this.getTiddlersAndContext(parameter).tiddlers;
};
// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
// The following properties are supported:
//
// place
// whereClause
// sortClause
// sortAscending
// actionName
// actionParameter
// scriptText
// tiddlyWikiPath
//
// All properties are optional.
// For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
var tiddlersAndContext = this.getTiddlersAndContext(parameter);
// Perform the action
var actionName = parameter.actionName ? parameter.actionName : "addToList";
var action = config.macros.forEachTiddler.actions[actionName];
if (!action) {
this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
return;
}
var actionHandler = action.handler;
actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};
// ---------------------------------------------------------------------------
// The actions
// ---------------------------------------------------------------------------
// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
// Parse the parameter
var p = 0;
// Check for extra parameters
if (parameter.length > p) {
config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
return;
}
// Perform the action.
var list = document.createElement("ul");
place.appendChild(list);
for (var i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
var listItem = document.createElement("li");
list.appendChild(listItem);
createTiddlyLink(listItem, tiddler.title, true);
}
};
abego.parseNamedParameter = function(name, parameter, i) {
var beginExpression = null;
if ((i < parameter.length) && parameter[i] == name) {
i++;
if (i >= parameter.length) {
throw "Missing text behind '%0'".format([name]);
}
return config.macros.forEachTiddler.paramEncode(parameter[i]);
}
return null;
}
// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
// Parse the parameter
var p = 0;
if (p >= parameter.length) {
this.handleError(place, "Missing expression behind 'write'.");
return;
}
var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
p++;
// Parse the "begin" option
var beginExpression = abego.parseNamedParameter("begin", parameter, p);
if (beginExpression !== null)
p += 2;
var endExpression = abego.parseNamedParameter("end", parameter, p);
if (endExpression !== null)
p += 2;
var noneExpression = abego.parseNamedParameter("none", parameter, p);
if (noneExpression !== null)
p += 2;
// Parse the "toFile" option
var filename = null;
var lineSeparator = undefined;
if ((p < parameter.length) && parameter[p] == "toFile") {
p++;
if (p >= parameter.length) {
this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
return;
}
filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
p++;
if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
p++;
if (p >= parameter.length) {
this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
return;
}
lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
p++;
}
}
// Check for extra parameters
if (parameter.length > p) {
config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
return;
}
// Perform the action.
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
var count = tiddlers.length;
var text = "";
if (count > 0 && beginExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
for (var i = 0; i < count; i++) {
var tiddler = tiddlers[i];
text += func(tiddler, context, count, i);
}
if (count > 0 && endExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);
if (count == 0 && noneExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
if (filename) {
if (lineSeparator !== undefined) {
lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
text = text.replace(/\n/mg,lineSeparator);
}
saveFile(filename, convertUnicodeToUTF8(text));
} else {
var wrapper = createTiddlyElement(place, "span");
wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
}
};
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
return {
place : placeParam,
whereClause : whereClauseParam,
sortClause : sortClauseParam,
sortAscending : sortAscendingParam,
script : scriptText,
actionName : actionNameParam,
actionParameter : actionParameterParam,
tiddlyWikiPath : tiddlyWikiPathParam,
inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
};
};
// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
if (!idPrefix) {
idPrefix = "store";
}
var lenPrefix = idPrefix.length;
// Read the content of the given file
var content = loadFile(this.getLocalPath(path));
if(content === null) {
throw "TiddlyWiki '"+path+"' not found.";
}
var tiddlyWiki = new TiddlyWiki();
// Starting with TW 2.2 there is a helper function to import the tiddlers
if (tiddlyWiki.importTiddlyWiki) {
if (!tiddlyWiki.importTiddlyWiki(content))
throw "File '"+path+"' is not a TiddlyWiki.";
tiddlyWiki.dirty = false;
return tiddlyWiki;
}
// The legacy code, for TW < 2.2
// Locate the storeArea div's
var posOpeningDiv = content.indexOf(startSaveArea);
var posClosingDiv = content.lastIndexOf(endSaveArea);
if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
throw "File '"+path+"' is not a TiddlyWiki.";
}
var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
// Create a "div" element that contains the storage text
var myStorageDiv = document.createElement("div");
myStorageDiv.innerHTML = storageText;
myStorageDiv.normalize();
// Create all tiddlers in a new TiddlyWiki
// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
var store = myStorageDiv.childNodes;
for(var t = 0; t < store.length; t++) {
var e = store[t];
var title = null;
if(e.getAttribute)
title = e.getAttribute("tiddler");
if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
title = e.id.substr(lenPrefix);
if(title && title !== "") {
var tiddler = tiddlyWiki.createTiddler(title);
tiddler.loadFromDiv(e,title);
}
}
tiddlyWiki.dirty = false;
return tiddlyWiki;
};
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
//
// (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
var script = context["script"];
var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
var fullText = (script ? script+";" : "")+functionText+";theFunction;";
return eval(fullText);
};
// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
var result = [];
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
tiddlyWiki.forEachTiddler(function(title,tiddler) {
if (func(tiddler, context, undefined, undefined)) {
result.push(tiddler);
}
});
return result;
};
// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
var message = "Extra parameter behind '"+actionName+"':";
for (var i = firstUnusedIndex; i < parameter.length; i++) {
message += " "+parameter[i];
}
this.handleError(place, message);
};
// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
var result =
(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
? 0
: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
? -1
: +1;
return result;
};
// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
var result =
(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
? 0
: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
? +1
: -1;
return result;
};
// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
// To avoid evaluating the sortClause whenever two items are compared
// we pre-calculate the sortValue for every item in the array and store it in a
// temporary property ("forEachTiddlerSortValue") of the tiddlers.
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
var count = tiddlers.length;
var i;
for (i = 0; i < count; i++) {
var tiddler = tiddlers[i];
tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
}
// Do the sorting
tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);
// Delete the temporary property that holds the sortValue.
for (i = 0; i < tiddlers.length; i++) {
delete tiddlers[i].forEachTiddlerSortValue;
}
};
// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
displayMessage(message);
};
// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
var message ="<<"+macroName;
for (var i = 0; i < params.length; i++) {
message += " "+params[i];
}
message += ">>";
displayMessage(message);
};
// Internal.
//
// Creates an element that holds an error message
//
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
var message = (exception.description) ? exception.description : exception.toString();
return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};
// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
if (place) {
this.createErrorElement(place, exception);
} else {
throw exception;
}
};
// Internal.
//
// Encodes the given string.
//
// Replaces
// "$))" to ">>"
// "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
var reGTGT = new RegExp("\\$\\)\\)","mg");
var reGT = new RegExp("\\$\\)","mg");
return s.replace(reGTGT, ">>").replace(reGT, ">");
};
// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
//
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
// Remove any location part of the URL
var hashPos = originalPath.indexOf("#");
if(hashPos != -1)
originalPath = originalPath.substr(0,hashPos);
// Convert to a native file format assuming
// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
var localPath;
if(originalPath.charAt(9) == ":") // pc local file
localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
localPath = unescape(originalPath.substr(7));
else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
localPath = unescape(originalPath.substr(5));
else // pc network file
localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
return localPath;
};
// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
"forEachTiddler");
//============================================================================
// End of forEachTiddler Macro
//============================================================================
//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
var n = prefix.length;
return (this.length >= n) && (this.slice(0, n) == prefix);
};
//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
var n = suffix.length;
return (this.length >= n) && (this.right(n) == suffix);
};
//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
return this.indexOf(substring) >= 0;
};
//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
for (var i = 0; i < this.length; i++) {
if (this[i] == item) {
return i;
}
}
return -1;
};
//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false.
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
return (this.indexOf(item) >= 0);
};
//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
for(var i = 0; i < items.length; i++) {
if (this.contains(items[i])) {
return true;
}
}
return false;
};
//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
//
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null]
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
for(var i = 0; i < items.length; i++) {
if (!this.contains(items[i])) {
return false;
}
}
return true;
};
} // of "install only once"
// Used Globals (for JSLint) ==============
// ... DOM
/*global document */
// ... TiddlyWiki Core
/*global convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink,
displayMessage, endSaveArea, hasClass, loadFile, saveFile,
startSaveArea, store, wikify */
//}}}
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
/***
<<checkForDataTiddlerPlugin>>
|''Name:''|FormTiddlerPlugin|
|''Version:''|1.0.6 (2007-06-24)|
|''Source:''|http://tiddlywiki.abego-software.de/#FormTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''Macros:''|formTiddler, checkForDataTiddlerPlugin, newTiddlerWithForm|
|''Requires:''|DataTiddlerPlugin|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Use form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).
''Syntax:''
|>|{{{<<}}}''formTiddler'' //tiddlerName//{{{>>}}}|
|//tiddlerName//|The name of the FormTemplate tiddler to be used to edit the data of the tiddler containing the macro.|
|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|
|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|
|//buttonLabel//|The label of the button|
|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|
|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
For details and how to use the macros see the [[introduction|FormTiddler Introduction]] and the [[examples|FormTiddler Examples]].
!Revision history
* v1.0.6 (2007-06-24)
** Fixed problem when using SELECT component in Internet Explorer (thanks to MaikBoenig for reporting)
* v1.0.5 (2006-02-24)
** Removed "debugger;" instruction
* v1.0.4 (2006-02-07)
** Bug: On IE no data is written to data section when field values changed (thanks to KenGirard for reporting)
* v1.0.3 (2006-02-05)
** Bug: {{{"No form template specified in <<formTiddler>>"}}} when using formTiddler macro on InternetExplorer (thanks to KenGirard for reporting)
* v1.0.2 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.1 (2005-12-22)
** Features:
*** Support InternetExplorer
*** Added newTiddlerWithForm Macro
* v1.0.0 (2005-12-14)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// FormTiddlerPlugin
//============================================================================
//============================================================================
if (!window.abego) window.abego = {};
abego.getOptionsValue = function(element,i) {
var v = element.options[i].value;
if (!v && element.options[i].text)
v = element.options[i].text;
return v;
};
version.extensions.FormTiddlerPlugin = {
major: 1, minor: 0, revision: 5,
date: new Date(2006, 2, 24),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"
};
// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window;
if (!TiddlyWiki.prototype.getTiddler) TiddlyWiki.prototype.getTiddler = function(title) { return t = this.tiddlers[title]; return (t != undefined && t instanceof Tiddler) ? t : null; }
//============================================================================
// formTiddler Macro
//============================================================================
// -------------------------------------------------------------------------------
// Configurations and constants
// -------------------------------------------------------------------------------
config.macros.formTiddler = {
// Standard Properties
label: "formTiddler",
version: {major: 1, minor: 0, revision: 4, date: new Date(2006, 2, 7)},
prompt: "Edit tiddler data using forms",
// Define the "setters" that set the values of INPUT elements of a given type
// (must match the corresponding "getter")
setter: {
button: function(e, value) {/*contains no data */ },
checkbox: function(e, value) {e.checked = value;},
file: function(e, value) {try {e.value = value;} catch(e) {/* ignore, possibly security error*/}},
hidden: function(e, value) {e.value = value;},
password: function(e, value) {e.value = value;},
radio: function(e, value) {e.checked = (e.value == value);},
reset: function(e, value) {/*contains no data */ },
"select-one": function(e, value) {config.macros.formTiddler.setSelectOneValue(e,value);},
"select-multiple": function(e, value) {config.macros.formTiddler.setSelectMultipleValue(e,value);},
submit: function(e, value) {/*contains no data */},
text: function(e, value) {e.value = value;},
textarea: function(e, value) {e.value = value;}
},
// Define the "getters" that return the value of INPUT elements of a given type
// Return undefined to not store any data.
getter: {
button: function(e, value) {return undefined;},
checkbox: function(e, value) {return e.checked;},
file: function(e, value) {return e.value;},
hidden: function(e, value) {return e.value;},
password: function(e, value) {return e.value;},
radio: function(e, value) {return e.checked ? e.value : undefined;},
reset: function(e, value) {return undefined;},
"select-one": function(e, value) {return config.macros.formTiddler.getSelectOneValue(e);},
"select-multiple": function(e, value) {return config.macros.formTiddler.getSelectMultipleValue(e);},
submit: function(e, value) {return undefined;},
text: function(e, value) {return e.value;},
textarea: function(e, value) {return e.value;}
}
};
// -------------------------------------------------------------------------------
// The formTiddler Macro Handler
// -------------------------------------------------------------------------------
config.macros.formTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
if (!config.macros.formTiddler.checkForExtensions(place, macroName)) {
return;
}
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// get the name of the form template tiddler
var formTemplateName = undefined;
if (i < params.length) {
formTemplateName = params[i];
i++;
}
if (!formTemplateName) {
config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
return;
}
// --- Processing ------------------------------------------
// Get the form template text.
// (This contains the INPUT elements for the form.)
var formTemplateTiddler = store.getTiddler(formTemplateName);
if (!formTemplateTiddler) {
config.macros.formTiddler.createErrorElement(place, "Form template '" + formTemplateName + "' not found.");
return;
}
var templateText = formTemplateTiddler.text;
if(!templateText) {
// Shortcut: when template text is empty we do nothing.
return;
}
// Get the name of the tiddler containing this "formTiddler" macro
// (i.e. the tiddler, that will be edited and that contains the data)
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);
// Append a "form" element.
var formName = "form"+formTemplateName+"__"+tiddlerName;
var e = document.createElement("form");
e.setAttribute("name", formName);
place.appendChild(e);
// "Embed" the elements defined by the templateText (i.e. the INPUT elements)
// into the "form" element we just created
wikify(templateText, e);
// Initialize the INPUT elements.
config.macros.formTiddler.initValuesAndHandlersInFormElements(formName, DataTiddler.getDataObject(tiddlerName));
}
// -------------------------------------------------------------------------------
// Form Data Access
// -------------------------------------------------------------------------------
// Internal.
//
// Initialize the INPUT elements of the form with the values of their "matching"
// data fields in the tiddler. Also setup the onChange handler to ensure that
// changes in the INPUT elements are stored in the tiddler's data.
//
config.macros.formTiddler.initValuesAndHandlersInFormElements = function(formName, data) {
// config.macros.formTiddler.trace("initValuesAndHandlersInFormElements(formName="+formName+", data="+data+")");
// find the form
var form = config.macros.formTiddler.findForm(formName);
if (!form) {
return;
}
try {
var elems = form.elements;
for (var i = 0; i < elems.length; i++) {
var c = elems[i];
var setter = config.macros.formTiddler.setter[c.type];
if (setter) {
var value = data[c.name];
if (value != null) {
setter(c, value);
}
c.onchange = onFormTiddlerChange;
} else {
config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+c.type+"'. (Element '"+c.name+"' in form '"+formName+"')");
}
}
} catch(e) {
config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+e);
}
}
// Internal.
//
// @return [may be null]
//
config.macros.formTiddler.findForm = function(formName) {
// We must manually iterate through the document's forms, since
// IE does not support the "document[formName]" approach
var forms = window.document.forms;
for (var i = 0; i < forms.length; i++) {
var form = forms[i];
if (form.name == formName) {
return form;
}
}
return null;
}
// Internal.
//
config.macros.formTiddler.setSelectOneValue = function(element,value) {
var n = element.options.length;
for (var i = 0; i < n; i++) {
element.options[i].selected = abego.getOptionsValue(element,i) == value;
}
}
// Internal.
//
config.macros.formTiddler.setSelectMultipleValue = function(element,value) {
var values = {};
for (var i = 0; i < value.length; i++) {
values[value[i]] = true;
}
var n = element.length;
for (var i = 0; i < n; i++) {
element.options[i].selected = !(!values[abego.getOptionsValue(element,i)]);
}
}
// Internal.
//
config.macros.formTiddler.getSelectOneValue = function(element) {
var i = element.selectedIndex;
return (i >= 0) ? abego.getOptionsValue(element,i) : null;
}
// Internal.
//
config.macros.formTiddler.getSelectMultipleValue = function(element) {
var values = [];
var n = element.length;
for (var i = 0; i < n; i++) {
if (element.options[i].selected) {
values.push(abego.getOptionsValue(element,i));
}
}
return values;
}
// -------------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------------
// Internal.
//
config.macros.formTiddler.checkForExtensions = function(place,macroName) {
if (!version.extensions.DataTiddlerPlugin) {
config.macros.formTiddler.createErrorElement(place, "<<" + macroName + ">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");
return false;
}
return true;
}
// Internal.
//
// Displays a trace message in the "TiddlyWiki" message pane.
// (used for debugging)
//
config.macros.formTiddler.trace = function(s) {
displayMessage("Trace: "+s);
}
// Internal.
//
// Display some error message in the "TiddlyWiki" message pane.
//
config.macros.formTiddler.displayFormTiddlerError = function(s) {
alert("FormTiddlerPlugin Error: "+s);
}
// Internal.
//
// Creates an element that holds an error message
//
config.macros.formTiddler.createErrorElement = function(place, message) {
return createTiddlyElement(place,"span",null,"formTiddlerError",message);
}
// Internal.
//
// Returns the name of the tiddler containing the given element.
//
config.macros.formTiddler.getContainingTiddlerName = function(element) {
return story.findContainingTiddler(element).id.substr(7);
}
// -------------------------------------------------------------------------------
// Event Handlers
// -------------------------------------------------------------------------------
// This function must be called by the INPUT elements whenever their
// data changes. Typically this is done through an "onChange" handler.
//
function onFormTiddlerChange (e) {
// config.macros.formTiddler.trace("onFormTiddlerChange "+e);
if (!e) var e = window.event;
var target = resolveTarget(e);
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(target);
var getter = config.macros.formTiddler.getter[target.type];
if (getter) {
var value = getter(target);
DataTiddler.setData(tiddlerName, target.name, value);
} else {
config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+target.type+"'. (Element '"+target.name+"' used in tiddler '"+tiddlerName+"')");
}
}
// ensure that the function can be used in HTML event handler
window.onFormTiddlerChange = onFormTiddlerChange;
// -------------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// -------------------------------------------------------------------------------
setStylesheet(
".formTiddlerError{color: #ffffff;background-color: #880000;}",
"formTiddler");
//============================================================================
// checkForDataTiddlerPlugin Macro
//============================================================================
config.macros.checkForDataTiddlerPlugin = {
// Standard Properties
label: "checkForDataTiddlerPlugin",
version: {major: 1, minor: 0, revision: 0, date: new Date(2005, 12, 14)},
prompt: "Check if the DataTiddlerPlugin exists"
}
config.macros.checkForDataTiddlerPlugin.handler = function(place,macroName,params) {
config.macros.formTiddler.checkForExtensions(place, config.macros.formTiddler.label);
}
//============================================================================
// newTiddlerWithForm Macro
//============================================================================
config.macros.newTiddlerWithForm = {
// Standard Properties
label: "newTiddlerWithForm",
version: {major: 1, minor: 0, revision: 1, date: new Date(2006, 1, 6)},
prompt: "Creates a new Tiddler with a <<formTiddler ...>> macro"
}
config.macros.newTiddlerWithForm.handler = function(place,macroName,params) {
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// get the name of the form template tiddler
var formTemplateName = undefined;
if (i < params.length) {
formTemplateName = params[i];
i++;
}
if (!formTemplateName) {
config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
return;
}
// get the button label
var buttonLabel = undefined;
if (i < params.length) {
buttonLabel = params[i];
i++;
}
if (!buttonLabel) {
config.macros.formTiddler.createErrorElement(place, "No button label specified in <<" + macroName + ">>.");
return;
}
// get the (optional) tiddlerName script and "askUser"
var tiddlerNameScript = undefined;
var askUser = false;
if (i < params.length) {
tiddlerNameScript = params[i];
i++;
if (i < params.length && params[i] == "askUser") {
askUser = true;
i++;
}
}
// --- Processing ------------------------------------------
if(!readOnly) {
var onClick = function() {
var tiddlerName;
if (tiddlerNameScript) {
try {
tiddlerName = eval(tiddlerNameScript);
} catch (ex) {
}
}
if (!tiddlerName || askUser) {
tiddlerName = prompt("Please specify a tiddler name.", askUser ? tiddlerName : "");
}
while (tiddlerName && store.getTiddler(tiddlerName)) {
tiddlerName = prompt("A tiddler named '"+tiddlerName+"' already exists.\n\n"+"Please specify a tiddler name.", tiddlerName);
}
// tiddlerName is either null (user canceled) or a name that is not yet in the store.
if (tiddlerName) {
var body = "<<formTiddler [["+formTemplateName+"]]>>";
var tags = [];
store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);
story.displayTiddler(null,tiddlerName,1);
}
}
createTiddlyButton(place,buttonLabel,buttonLabel,onClick);
}
}
//}}}
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{
window.hideWhenLastTest = false;
window.removeElementWhen = function(test,place) {
window.hideWhenLastTest = test;
if (test) {
removeChildren(place);
place.parentNode.removeChild(place);
}
};
merge(config.macros,{
hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( eval(paramString), place);
}},
showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !eval(paramString), place);
}},
hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAny(params), place);
}},
showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAny(params), place);
}},
hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
}},
showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
}},
hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title == params[0], place);
}},
showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title != params[0], place);
}},
'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !window.hideWhenLastTest, place);
}}
});
//}}}
{{homeTitle{Mobil elevliste}}}
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2008.03.03 [1.9.2] corrected declaration of wikifyPlainText() for 'TW 2.1.x compatibility fallback' (fixes Safari "parse error")
2008.02.23 [1.9.1] in onclick function, use string instead of array for 'bufferedHTML' attribute on link element (fixes IE errors)
2008.02.21 [1.9.0] 'onclick' scripts now allow returned text (or document.write() calls) to be wikified into a span that immediately follows the onclick link. Also, added default 'return false' handling if no return value provided (prevents HREF from being triggered -- return TRUE to allow HREF to be processed). Thanks to Xavier Verges for suggestion and preliminary code.
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 9, revision: 2, date: new Date(2008,3,3)};
config.formatters.push( {
name: "inlineJavascript",
match: "\\<script",
lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
handler: function(w) {
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var src=lookaheadMatch[1];
var label=lookaheadMatch[2];
var tip=lookaheadMatch[3];
var key=lookaheadMatch[4];
var show=lookaheadMatch[5];
var code=lookaheadMatch[6];
if (src) { // load a script library
// make script tag, set src, add to body to execute, then remove for cleanup
var script = document.createElement("script"); script.src = src;
document.body.appendChild(script); document.body.removeChild(script);
}
if (code) { // there is script code
if (show) // show inline script code in tiddler output
wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
if (label) { // create a link to an 'onclick' script
// add a link, define click handler, save code in link (pass 'place'), set link attributes
var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
link.code="function _out(place){"+fixup+"\n};_out(this);"
link.tiddler=w.tiddler;
link.onclick=function(){
this.bufferedHTML="";
try{ var r=eval(this.code);
if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
if(this.bufferedHTML.length)
s.innerHTML=this.bufferedHTML;
if((typeof(r)==="string")&&r.length) {
wikify(r,s,null,this.tiddler);
return false;
} else return r!==undefined?r:false;
} catch(e){alert(e.description||e.toString());return false;}
};
link.setAttribute("title",tip||"");
var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
link.setAttribute("href",URIcode);
link.style.cursor="pointer";
if (key) link.accessKey=key.substr(0,1); // single character only
}
else { // run inline script code
var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
var code="function _out(place){"+fixup+"\n};_out(w.output);"
try { var out=eval(code); } catch(e) { out=e.description?e.description:e.toString(); }
if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
}
}
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
}
} )
//}}}
// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
if(limit > 0) text = text.substr(0,limit);
var wikifier = new Wikifier(text,formatter,null,tiddler);
return wikifier.wikifyPlain();
}
//}}}
For at komme i gang med denne tiddlywiki skal du ændre på følgende tiddlere:
* [[Sidetitel|SiteTitle]] & [[Sideundertitel|SiteSubtitle]]: Hjemmesidens titel og undertitel, som de vises foroven (efter du har gemt vil de også vises i browseren titelpanel)
* [[SideUrl|SiteUrl]]: Hjemmesidens adresse (som bruges til RSSFeed)
* Indstil [[Muligheder|Options]] og [[Tweaks|iTWTweaks]]
* Tiddlere taggede med [[Menu]] bliver vist i <<tag Menu>>
* Tiddlere taggede med [[Home]] bliver vist på hjemmesidens startside når TiddlyWikien bliver åbnet.
*Mere information her : http://iTW.BidiX.info/
*iTW er licenseret [[BSD Open Source License]] send gerne ønsker og kommentarer til BidiX (På engelsk tak! red)
/***
|Name|ListboxPlugin|
|Source|http://www.TiddlyTools.com/#ListboxPlugin|
|Documentation|http://www.TiddlyTools.com/#ListboxPluginInfo|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|set tiddler fields by selecting enumerated values from a listbox or droplist|
The {{{<<select>>}}} macro allows you to set tiddler field values by selecting pre-configured enumerated values from a listbox/droplist control.
!!!!!Documentation
>see [[ListboxPluginInfo]]
!!!!!Revisions
<<<
2008.07.22 [1.1.0] added "=cookiename" syntax for storing selected value in cookie instead of a tiddler field
|please see [[ListboxPluginInfo]] for additional revision details|
2007.05.12 [0.5.0] started
<<<
!!!!!Code
***/
//{{{
version.extensions.ListboxPlugin= {major: 1, minor: 1, revision: 0, date: new Date(2008,7,22)};
config.macros.select = {
tooltip: "select a value for %0@%1",
blankTooltip: "set %0@%1=[null] (delete field value)",
valueTooltip: "set %0@%1=%2",
otherLabel: "other",
otherTooltip: "set %0@%1=[???] (enter custom value)",
otherPrompt: "enter a value for '%0'",
editLabel: "edit list...",
editTooltip: "edit '%0' list definition (%1)",
changeMsg: "setting %0@%1=%2",
verbose: false,
hereKeyword: "here",
defaultTarget: "SiteFields",
handler:
function(place,macroName,params,wikifier,paramString,tiddler) {
// get containing tiddler (or use default "SiteFields" catch-all tiddler)
var here=story.findContainingTiddler(place);
var targetID=here?here.getAttribute("tiddler"):this.defaultTarget;
// get field name
var field=params.shift();
var pos=field.indexOf("@"); // if non-default target ("field@tiddler" syntax)
if(pos!=-1) { // split field into field and tiddlername.
if (field.substr(pos+1)!=this.hereKeyword) // "here" == use default target
targetID=field.substr(pos+1); // switch to different target tiddler
field=field.substr(0,pos);
}
// if no field name, do nothing
if(!field || !field.length) return;
// if field starts with "=", it is an option cookie instead of a tiddler field
if (field.substr(0,1)=="=") targetID="(system)";
var p=params.shift();
var rows="0"; if (p.substr(0,5)=="rows:") { rows=p.substr(5); p=params.shift(); } // optional list height in lines
var width="auto"; if (p.substr(0,6)=="width:") { width=p.substr(6); p=params.shift(); } // optional CSS width
var autosave=(p.toLowerCase()=="autosave"); if (autosave) p=params.shift(); // optional autosave
var allowBlank=(p.toLowerCase()=="allowblank"); if (allowBlank) p=params.shift(); // add optional empty item
var allowOther=(p.toLowerCase()=="allowother"); if (allowOther) p=params.shift(); // add optional "other: ____" item
if (tiddler && !story.isDirty(tiddler.title)) autosave=true; // if tiddler is in VIEW mode, force autosave
var list=[];
if (p.substr(0,1)=="+"||p.substr(0,1)=="*") { // get list from HR-separated tiddler (* means wikify source first)
var listsrc=p.substr(1);
var listtxt=store.getTiddlerText(listsrc);
var wikifyData=p.substr(0,1)=="*"; if (wikifyData) listtxt=this.getWikifiedData(listtxt);
var separator="\n";
if (listtxt && listtxt.indexOf("\n----\n")!=-1) separator="\n----\n";
if (listtxt && listtxt.length) var list=listtxt.split(separator);
var allowEdit=(params[0] && params[0].toLowerCase()=="allowedit"); // add optional "edit list..." item
if (allowEdit) p=params.shift();
}
else if (p.substr(0,1)=="=") { // get list from tagged tiddlers
var tids=store.getTaggedTiddlers(p.substr(1));
for (var t=0; t<tids.length; t++) list.push(tids[t].title);
}
else { // get list from macro params: "value value value ..." or "label=value label=value label=value ..."
while (p) {
var parts=p.split("=");
var label=parts[0]; var v=parts[1]?parts[1]:parts[0];
list.push(label+"="+v);
p=params.shift();
}
}
// register notification handler for ALL tiddler changes (to sync lists)
store.addNotification(null,this.refresh);
// render the control
this.render(createTiddlyElement(place,"span"), null, targetID, field, list, listsrc, wikifyData, rows, width, autosave, allowBlank, allowOther, allowEdit);
},
getWikifiedData: // wikify tiddler content, then extract text WITH newlines and HRs included
function(txt) {
var e=createTiddlyElement(document.body,"div"); wikify(txt,e);
var breaks=e.getElementsByTagName("br");
for (var b=0; b<breaks.length; b++) breaks[b].parentNode.insertBefore(document.createTextNode("\n"),breaks[b]);
var lines=e.getElementsByTagName("hr");
for (var l=0; l<lines.length; l++) lines[l].parentNode.insertBefore(document.createTextNode("----\n"),lines[l]);
var items=e.getElementsByTagName("li");
for (var i=0; i<items.length; i++) items[i].parentNode.insertBefore(document.createTextNode("\n"),items[i]);
var txt=getPlainText(e); removeNode(e); return txt;
},
refresh:
function (title) {
var lists=document.getElementsByTagName("select");
for (i=0; i<lists.length; i++) {
if (lists[i].getAttribute("listsrc")==title) {
var here=lists[i];
var place=here.parentNode;
var targetID=here.getAttribute("tiddler");
var field=here.getAttribute("edit");
var listsrc=here.getAttribute("listsrc");
var rows=here.getAttribute("rows");
var width=here.getAttribute("width");
var autosave=here.getAttribute("autosave")=="true";
var allowBlank=here.getAttribute("allowBlank")=="true";
var allowOther=here.getAttribute("allowOther")=="true";
var allowEdit=here.getAttribute("allowEdit")=="true";
var wikifyData=here.getAttribute("wikifyData")=="true";
// get the list
var listtxt=store.getTiddlerText(listsrc,""); if (wikifyData) listtxt=config.macros.select.getWikifiedData(listtxt);
var separator="\n"; if (listtxt && listtxt.indexOf("\n----\n")!=-1) separator="\n----\n";
var list=[]; if (listtxt && listtxt.length) var list=listtxt.split(separator);
// re-render control
config.macros.select.render(place, here, targetID, field, list, listsrc, wikifyData, rows, width, autosave, allowBlank, allowOther, allowEdit);
}
}
},
render:
function (place, here, targetID, field, list, listsrc, wikifyData, rows, width, autosave, allowBlank, allowOther, allowEdit) {
// use selected value from existing listbox (except for "edit list..." item)
if (here && here.selectedIndex!=-1 && here.options[here.selectedIndex].text!=config.macros.select.editLabel)
{ var val=here.value; if (val && !val.length) val=undefined; }
// if listbox doesn't yet exist, or 'edit list' item was selected, use existing value from field (if any)
if (!val) var val=(field.substr(0,1)=='=')?
config.options[field.substr(1)]:store.getValue(targetID,field);
var count=0; var options="";
// add default 'undefined' item
if (val==undefined || allowBlank) {
var title=this.blankTooltip.format([field,targetID]);
options+='<option value="" title="'+title+'"></option>';
count++;
}
// add enumerated items
var isOther=(val!=undefined);
for (opt=0; opt<list.length; opt++) {
var lines=list[opt].split("\n"); var parts=lines[0].split("=");
var label=parts[0];
var v=parts[1]?parts[1]:parts[0];
var title=lines[1]?lines[1]:this.valueTooltip.format([field,targetID,v]);
options+='<option value="'+v+'" '+(val==v?'selected':'')+' title="'+title+'">'+label+'</option>';
if (val==v) isOther=false; // found matching value in list
count++;
}
// add other... item
if (isOther||allowOther) {
var label="other"+(isOther?(": "+val):"...");
var v=isOther?val:"";
var title=this.otherTooltip.format([field,targetID]);
options+='<option value="'+v+'" '+(isOther?'selected':'')+' title="'+title+'">'+label+'</option>';
count++;
}
// add edit list... item
if (listsrc && (!store.getTiddlerText(listsrc) || allowEdit)) {
var title=this.editTooltip.format([field,listsrc]);
options+='<option value="'+listsrc+'" title="'+title+'">'+this.editLabel+'</option>';
count++;
}
// construct full HTML
var html='<select ';
html+=(val!=undefined?'value="'+val+'" ':'')+'" edit="'+field+'" ';
html+='onclick="return config.macros.select.onClick(this,event)" ';
html+='onchange="return config.macros.select.onChange(this,event)" ';
html+='ondblclick="return false" ';
html+='autosave="'+autosave+'" allowBlank="'+allowBlank+'" ';
html+='allowOther="'+allowOther+'" allowEdit="'+allowEdit+'" ';
html+='rows="'+rows+'" size="'+(rows!=0?rows:count)+'" ';
html+='tiddler="'+targetID+'" '+'" listsrc="'+listsrc+'" wikifyData="'+wikifyData+'" ';
html+='title="'+this.tooltip.format([field,targetID])+'" style="width:'+width+'">'+options+'</select>';
// pass to browser for rendering
place.innerHTML=html;
},
onClick:
function(here,event) {
var label=config.macros.select.otherLabel;
if (here.getAttribute("allowother")=="true" && here.options[here.selectedIndex].text.substr(0,label.length)==label)
here.onchange.apply(here,arguments);
},
onChange:
function(here,event) {
if (here.options[here.selectedIndex].text==config.macros.select.editLabel) {
story.displayTiddler(story.findContainingTiddler(here),here.value,DEFAULT_EDIT_TEMPLATE);
return false;
}
var label=config.macros.select.otherLabel;
if (here.getAttribute("allowother")=="true" && here.options[here.selectedIndex].text.substr(0,label.length)==label) {
var newval=prompt(config.macros.select.otherPrompt.format([here.getAttribute("edit")]),here.value);
if (!newval) {// user cancelled
var v=store.getValue(here.getAttribute("tiddler"),here.getAttribute("edit"));
{ here.value=v; if (v==undefined) here.selectedIndex=0; return false; }
};
here.options[here.selectedIndex].value=newval;
here.options[here.selectedIndex].text=config.macros.select.otherLabel+": "+newval;
here.value=newval;
}
if (here.getAttribute("autosave")=="true") config.macros.select.setFieldValue(here);
return false;
},
setFieldValue: function(here) {
var tid=here.getAttribute("tiddler"); if (!tid || !tid.length) return; // no target, do nothing
var field=here.getAttribute("edit");
if (field.substr(0,1)=='=') { // option cookie instead of tiddler field
config.macros.option.propagateOption(field.substr(1),"value",here.value,"input");
return;
}
// if tiddler doesn't exist, create it...
if (!store.tiddlerExists(tid)) store.saveTiddler(tid,tid,"",config.options.txtUserName,new Date(),[]);
// set the field value in the target tiddler
store.setValue(tid,field,here.value.length?here.value:null); // if value is blank, delete field
// touch target tiddler so that modified and modifier are updated
var t=store.getTiddler(tid);
store.saveTiddler(tid,tid,t.body,config.options.txtUserName,new Date(),t.tags,t.fields);
if (config.macros.select.verbose) // tell user what happened
{ clearMessage(); displayMessage(config.macros.select.changeMsg.format([field,tid,here.value])); }
}
}
//}}}
<<tag Elev>><<tag Lærere>><<tag Syg>><<tag HU>><<tag 9>><<tag 10>><<tag Adressebog>><<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>
/***
|''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);
}
//}}}
<<forEachTiddler where 'tiddler.tags.contains("Elev") && tiddler.fields["k-gruppe"] && tiddler.fields["k-gruppe"].contains(context.viewerTiddler.title)'
sortBy 'tiddler.fields["title"]'
write
'(index < 200)? "|"+(index+1)+"|[["+tiddler.title+"]] | <<tag "+tiddler.fields["gang"]+" \>\> | [["+tiddler.fields["kl"] +"]] | <<toggleTag HU [["+tiddler.title+"]] - \>\> | <<toggleTag Syg [["+tiddler.title+"]] - \>\> ||[img["+store.getValue(tiddler,"title")+"|"+store.getValue(tiddler,"billede")+"]["+tiddler.title+"]] |\n" : ""'
begin '"|sortable|k\n"
+"|>|>|>|!<<wikify [[%0]] fuldenavn@here \>\> | <<tiddler HUUpdate\>\> | <<tiddler SygeUpdate\>\> | |h\n"
+"|!#| <<wikify [img[%1|%0][%1]] billede@here fuldenavn@here \>\> |<<tag GangOversigt Gang \>\>|<<tag Kl \>\>| <<tag HU \>\> | <<tag Syg \>\> ||h\n"'
end 'count+" kontaktgruppe elever\n"' none '"ingen kontaktelever \n"'>>
<<forEachTiddler where 'tiddler.tags.contains("Lærere") && tiddler.fields["fuldenavn"]&& tiddler.fields["billede"] '
sortBy 'tiddler.fields["title"]'
write
'(index < 200)? "| "+(index+1)+"|<<tag "+tiddler.title+" \>\> | [["+tiddler.fields["fuldenavn"]+"|"+tiddler.title+"]] | [img["+tiddler.fields["fuldenavn"]+"|"+store.getValue(tiddler,"billede")+"]["+tiddler.title+"]] |\n" : ""'
begin '"|sortable|k\n"
+"|>|>|>| !<<tag Lærere \>\> |h\n"
+"|!#| <<tag Lærere Init \>\> | fulde navn ||h\n"'
end 'count+" stk Lærere\n"' none '"Ingen Lærere\n"'>>
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='toolbar' macro='toolbar +saveTiddler closeOthers -cancelTiddler deleteTiddler wikibar'></div>
<div style='clear:both'></div>
<div class='viewer'>
<table class='borderless' style='width:100%'><tr>
<td style='width:10%'>
<div class='small'>LærerInitialer (tiddler navn):</div>
<div class='editor' macro='select title rows:1 width:100% allowBlank allowOther +LærerListe allowEdit'></div>
<div class='small'>Tlf (må videregives):</div>
<div class='editor' macro='select telefon rows:1 width:100% allowBlank allowOther +TelefonListe allowEdit'></div>
<div class='small'>Ganglærer på:</div>
<div class='editor' macro='select gang rows:1 width:100% allowBlank allowOther +GangListe allowEdit'></div>
<div class='small'>Fast ugentlig vagtdag:</div>
<div class='editor' macro='select vagt rows:1 width:100% allowBlank allowOther Mandag Tirsdag Onsdag Torsdag Fredag Lørdag Søndag '></div>
</td><td style='width:20%'>
<div class='small'>Fulde navn:</div>
<div class='editor' macro='select fuldenavn rows:1 width:100% allowBlank allowOther +LærerListe allowEdit'></div>
<div class='small'>Email:</div>
<div class='editor' macro='select email rows:1 width:100% allowBlank allowOther +EmailListe allowEdit'></div>
<div class='small'>billede URL (jpg/gif):</div>
<div class='editor' macro='edit billede'></div>
</td></table>
<div class='small borderless'><span class='small'>Note (tekst):</span></div>
<div class='editor' macro='edit text 10'></div>
<div class='editor' macro='edit tags'></div>
<div class='toolbar editorFooter' style='text-align:left !important;float:left !important'>
<span macro='message views.editor.tagPrompt'></span><span class macro='newTiddler label: Adressebog title: {{tiddler.fields.fuldenavn}} tag: {{tiddler.title}} Adressebog text: {{store.getTiddlerText("AdresseTabs")}} ' </span>
<span macro='tagChooser'></span>
</div>
<div style='clear:both'></div>
</div><!-- viewer -->
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ElevViewToolbar]]'> </span><span macro='email to:{{tiddler.fields.email}} permalink:"true"'></span></div>
<div macro="hideWhenTaggedAny noTitle">
<div <span class='title'><span macro='view title'></span></div>
<td <span class macro='newJournalHere label:SygDD tag:"NoteArkiv" text:"Skriv sygenotater her"' ></span></td>
<td <span class macro="tiddler SaveThisTiddler " ></span>
</span><span class='subtitle'><span style='white-space:nowrap' macro='view modified date [[DDD, DDe MMM YYYY]]'></div></span>
<div macro="hideWhenTaggedAny systemTool systemList Lærere">
<div class='tagged' macro='tags'></div></div>
<div class='tagClear'></div>
<div <span class='menubox' style='float:center;margin:0em'
<span macro="toggleTag Syg . -"></span><span macro="tag Syg "</span><span macro="toggleTag -Middag . -"></span><span macro="tag -Middag "</span><span macro="toggleTag -Rengøring . -"></span><span macro="tag -Ren "</span><span macro="toggleTag HU . -"></span><span macro="tag HU "</span><span macro="toggleTag Andet . -"></span><span macro="tag Andet "</span><span macro="toggleTag Fri . -"></span><span macro="tag Fri "</span> </div>
<table <span class='viewer'>
<div class='tagClear'></div></span><span macro='tag Adressebog Kontakt '</span><span macro='tag Lærere Lærer:'></span><span macro='tag TelefonListe Tlf:'></span><span macro='wikify "[[%0|TelefonListe]]" telefon'</span>
<span macro='tag Vagt Vagt:'></span><span macro='wikify "[[%0|VagtPlan]]" vagt'></span>
<span macro='tag GangOversigt Gang:'></span><span macro='wikify "[[%0]]" gang'></span><span class macro='tiddler LærerTabel'>
</span></span></div><div<span macro='wikify "//@@bgcolor(#99ff33):Besked:@@//"'</span><span macro='wikify "@@color(#cc0000): %0@@" text'</span>
</td></tr></div>
</div>
<div class='tagClear'></div>
<!--}}}-->
<<tag Menu>>
<<tag Adressebog AddressArchive>>
<<tag Elev Student>>
<<tag Lærere Teacher>>
[[GettingStarted]]
@@[[TestCase]]@@
!Basic
Disse interface indstillinger til TiddlyWiki bliver gemt i din browser
Dit brugernavn til signering af dine edits. Skriv det som et WikiOrd (f.eks. JensHansen)
Brugernavn: <<option txtUserName>>
<<option chkAutoSave>> GemAutomatisk
<<option chkRegExpSearch>> RegExpSearch
<<option chkCaseSensitiveSearch>> SøgPåStoreOgSmåBogstaver
!Upload
UploadBrugerNavn : <<option txtUploadUserName>>
UploadPassword : <<option pasUploadPassword>>
UploadFilnavn : <<option txtUploadFilename>>
UploadStoreUrl :<<option txtUploadStoreUrl>>
UploadDir :<<option txtUploadDir>>
UploadFilnavn : <<option txtUploadFilename>>
UploadBackupDir : <<option txtUploadBackupDir>>
UploadLog : <<option chkUploadLog>>
UploadLogMaxLine : <<option txtUploadLogMaxLine>>
!~UploadTiddler
UploadTiddler: <<option chkUploadTiddler>>
UploadTiddlerStoreUrl : <<option txtUploadTiddlerStoreUrl>>
----
Se også [[avancerede muligheder|AdvancedOptions]] og [[Tweaks|iTWTweaks]]
/***
|Name:|NewHerePlugin|
|Description:|Creates the new here and new journal macros|
|Version:|3.0 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#NewHerePlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
merge(config.macros, {
newHere: {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
wikify("<<newTiddler "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
}
},
newJournalHere: {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
wikify("<<newJournal "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
}
}
});
//}}}
<<tiddler ContactsFormTemplate>><data>{"email":"humamamm@gmail.com"}</data>
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.9 (2007-07-14)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts.
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features"). E.g. you may create links to the parts (e.g. {{{[[Quotes/BAX95]]}}} or {{{[[Hobbies|AboutMe/Hobbies]]}}}), use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.
''Syntax:''
|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//. <<br>>If you use a partName containing spaces you need to quote it (e.g. {{{"Major Overview"}}} or {{{[[Shortcut List]]}}}).|
|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
|<html><i>any tiddler content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Applications<html><a name="Applications"/></html>
!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.
Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Citation Index<html><a name="Citation"/></html>
Create a tiddler "Citations" that contains your "citations".
Wrap every citation with a part and a proper name.
''Example''
{{{
<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.//
in //Proc. ICSM//, 1998.</part>
<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.//
Thesis, Uni Stuttgart, 2002.</part>
<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.//
in //Proc. ICSM//, 1999.</part>
}}}
You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
{{{
* Item 1
* Item 2
* Item 3
}}}
into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.
Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.
''Example''
{{{
|!Subject|!Items|
|subject1|<<tiddler ./Cell1>>|
|subject2|<<tiddler ./Cell2>>|
<part Cell1 hidden>
* Item 1
* Item 2
* Item 3
</part>
...
}}}
Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".
BTW: The same approach can be used to create bullet lists with items that contain more than one line.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Creating Tabs<html><a name="Tabs"/></html>
The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.
With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.
''Example''
The standard tabs at the sidebar are defined by the following eight tiddlers:
* SideBarTabs
* TabAll
* TabMore
* TabMoreMissing
* TabMoreOrphans
* TabMoreShadowed
* TabTags
* TabTimeline
Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
{{{
<<tabs txtMainTab
Timeline Timeline SideBarTabs/Timeline
All 'All tiddlers' SideBarTabs/All
Tags 'All tags' SideBarTabs/Tags
More 'More lists' SideBarTabs/More>>
<part Timeline hidden><<timeline>></part>
<part All hidden><<list all>></part>
<part Tags hidden><<allTags>></part>
<part More hidden><<tabs txtMoreTab
Missing 'Missing tiddlers' SideBarTabs/Missing
Orphans 'Orphaned tiddlers' SideBarTabs/Orphans
Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
<part Missing hidden><<list missing>></part>
<part Orphans hidden><<list orphans>></part>
<part Shadowed hidden><<list shadowed>></part>
}}}
Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.
E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
{{{
<<forEachTiddler
sortBy 'tiddler.modified' descending
write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
}}}
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Using Sliders<html><a name="Sliders"/></html>
Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature
''Example''
In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
{{{
...
<<slider chkAboutDetails About/Details details "Click here to see more details">>
<part Details hidden>
To give you a better overview ...
</part>
...
}}}
Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Revision history<html><a name="Revisions"/></html>
* v1.0.9 (2007-07-14)
** Bugfix: Error when using the SideBarTabs example and switching between "More" and "Shadow". Thanks to cmari for reporting the issue.
* v1.0.8 (2007-06-16)
** Speeding up display of tiddlers containing multiple pard definitions. Thanks to Paco Rivière for reporting the issue.
** Support "./partName" syntax inside <<tabs ...>> macro
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Code<html><a name="Code"/></html>
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
//{{{
//============================================================================
// PartTiddlerPlugin
// Ensure that the PartTiddler Plugin is only installed once.
//
if (!version.extensions.PartTiddlerPlugin) {
version.extensions.PartTiddlerPlugin = {
major: 1, minor: 0, revision: 9,
date: new Date(2007, 6, 14),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
};
if (!window.abego) window.abego = {};
if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");
//============================================================================
// Common Helpers
// Looks for the next newline, starting at the index-th char of text.
//
// If there are only whitespaces between index and the newline
// the index behind the newline is returned,
// otherwise (or when no newline is found) index is returned.
//
var skipEmptyEndOfLine = function(text, index) {
var re = /(\n|[^\s])/g;
re.lastIndex = index;
var result = re.exec(text);
return (result && text.charAt(result.index) == '\n')
? result.index+1
: index;
}
//============================================================================
// Constants
var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
var partEndTagREString = "<\\/part>";
var partEndTagString = "</part>";
//============================================================================
// Plugin Specific Helpers
// Parse the parameters inside a <part ...> tag and return the result.
//
// @return [may be null] {partName: ..., isHidden: ...}
//
var parseStartTagParams = function(paramText) {
var params = paramText.readMacroParams();
if (params.length == 0 || params[0].length == 0) return null;
var name = params[0];
var paramsIndex = 1;
var hidden = false;
if (paramsIndex < params.length) {
hidden = params[paramsIndex] == "hidden";
paramsIndex++;
}
return {
partName: name,
isHidden: hidden
};
}
// Returns the match to the next (end or start) part tag in the text,
// starting the search at startIndex.
//
// When no such tag is found null is returned, otherwise a "Match" is returned:
// [0]: full match
// [1]: matched "end" tag (or null when no end tag match)
// [2]: matched "start" tag (or null when no start tag match)
// [3]: content of start tag (or null if no start tag match)
//
var findNextPartEndOrStartTagMatch = function(text, startIndex) {
var re = new RegExp(partEndOrStartTagRE);
re.lastIndex = startIndex;
var match = re.exec(text);
return match;
}
//============================================================================
// Formatter
// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
//
// @return true if a complete part section (including the end tag) could be processed, false otherwise.
//
var handlePartSection = function(w) {
var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
if (!tagMatch) return false;
if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;
// Parse the start tag parameters
var arguments = parseStartTagParams(tagMatch[3]);
if (!arguments) return false;
// Continue processing
var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
if (endMatch && endMatch[1]) {
if (!arguments.isHidden) {
w.nextMatch = startTagEndIndex;
w.subWikify(w.output,partEndTagREString);
}
w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
return true;
}
return false;
}
config.formatters.push( {
name: "part",
match: "<part\\s+[^>]+>",
handler: function(w) {
if (!handlePartSection(w)) {
w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
}
}
} )
//============================================================================
// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers
// as tiddlers.
var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)
// Return the match to the first <part ...> tag of the text that has the
// requrest partName.
//
// @return [may be null]
//
var findPartStartTagByName = function(text, partName) {
var i = 0;
while (true) {
var tagMatch = findNextPartEndOrStartTagMatch(text, i);
if (!tagMatch) return null;
if (tagMatch[2]) {
// Is start tag
// Check the name
var arguments = parseStartTagParams(tagMatch[3]);
if (arguments && arguments.partName == partName) {
return tagMatch;
}
}
i = tagMatch.index+tagMatch[0].length;
}
}
// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler
// object, using fullName as the Tiddler's title.
//
// All remaining properties of the new Tiddler (tags etc.) are inherited from
// the parentTiddler.
//
// @return [may be null]
//
var getPart = function(parentTiddler, partName, fullName) {
var text = parentTiddler.text;
var startTag = findPartStartTagByName(text, partName);
if (!startTag) return null;
var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);
if (indexOfEndTag >= 0) {
var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
var partTiddler = new Tiddler();
partTiddler.set(
fullName,
partTiddlerText,
parentTiddler.modifier,
parentTiddler.modified,
parentTiddler.tags,
parentTiddler.created);
partTiddler.abegoIsPartTiddler = true;
return partTiddler;
}
return null;
}
// Hijack the store.fetchTiddler to recognize the "part" addresses.
//
var hijackFetchTiddler = function() {
var oldFetchTiddler = store.fetchTiddler ;
store.fetchTiddler = function(title) {
var result = oldFetchTiddler.apply(this, arguments);
if (!result && title) {
var i = title.lastIndexOf('/');
if (i > 0) {
var parentName = title.substring(0, i);
var partName = title.substring(i+1);
var parent = (parentName == ".")
? store.resolveTiddler(currentParent)
: oldFetchTiddler.apply(this, [parentName]);
if (parent) {
return getPart(parent, partName, parent.title+"/"+partName);
}
}
}
return result;
};
};
// for debugging the plugin is not loaded through the systemConfig mechanism but via a script tag.
// At that point in the "store" is not yet defined. In that case hijackFetchTiddler through the restart function.
// Otherwise hijack now.
if (!store) {
var oldRestartFunc = restart;
window.restart = function() {
hijackFetchTiddler();
oldRestartFunc.apply(this,arguments);
};
} else
hijackFetchTiddler();
// The user must not edit a readOnly/partTiddler
//
config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
// Tiddler.isReadOnly was introduced with TW 2.0.6.
// For older version we explicitly check the global readOnly flag
if (config.commands.editTiddler.oldIsReadOnlyFunction) {
if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
} else {
if (readOnly) return true;
}
return this.abegoIsPartTiddler;
}
config.commands.editTiddler.handler = function(event,src,title)
{
var t = store.getTiddler(title);
// Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
// or the tiddler is not readOnly
if(!t || !t.abegoIsPartTiddler)
{
clearMessage();
story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
story.focusTiddler(title,"text");
return false;
}
}
// To allow the "./partName" syntax in macros we need to hijack
// the invokeMacro to define the "currentParent" while it is running.
//
var oldInvokeMacro = window.invokeMacro;
function myInvokeMacro(place,macro,params,wikifier,tiddler) {
var oldCurrentParent = currentParent;
if (tiddler) currentParent = tiddler;
try {
oldInvokeMacro.apply(this, arguments);
} finally {
currentParent = oldCurrentParent;
}
}
window.invokeMacro = myInvokeMacro;
// To correctly support the "./partName" syntax while refreshing we need to hijack
// the config.refreshers.tiddlers to define the "currentParent" while it is running.
//
(function() {
var oldTiddlerRefresher= config.refreshers.tiddler;
config.refreshers.tiddler = function(e,changeList) {
var oldCurrentParent = currentParent;
try {
currentParent = e.getAttribute("tiddler");
return oldTiddlerRefresher.apply(this,arguments);
} finally {
currentParent = oldCurrentParent;
}
};
})();
// Support "./partName" syntax inside <<tabs ...>> macro
(function() {
var extendRelativeNames = function(e, title) {
var nodes = e.getElementsByTagName("a");
for(var i=0; i<nodes.length; i++) {
var node = nodes[i];
var s = node.getAttribute("content");
if (s && s.indexOf("./") == 0)
node.setAttribute("content",title+s.substr(1));
}
};
var oldHandler = config.macros.tabs.handler;
config.macros.tabs.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
var result = oldHandler.apply(this,arguments);
if (tiddler)
extendRelativeNames(place, tiddler.title);
return result;
};
})();
// Scroll the anchor anchorName in the viewer of the given tiddler visible.
// When no tiddler is defined use the tiddler of the target given event is used.
window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
var tiddlerElem = null;
if (tiddler) {
tiddlerElem = document.getElementById(story.idPrefix + tiddler);
}
if (!tiddlerElem && evt) {
var target = resolveTarget(evt);
tiddlerElem = story.findContainingTiddler(target);
}
if (!tiddlerElem) return;
var children = tiddlerElem.getElementsByTagName("a");
for (var i = 0; i < children.length; i++) {
var child = children[i];
var name = child.getAttribute("name");
if (name == anchorName) {
var y = findPosY(child);
window.scrollTo(0,y);
return;
}
}
}
} // of "install only once"
//}}}
/***
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
/***
|''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"
});
*/
//}}}
<<option pasUploadPassword>>
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.5.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.''
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2009.01.06 [1.5.1] reversed logic so that title-as-prefix takes precedence over tag-matched prefix
2008.12.18 [1.5.0] added handling for using tiddler //title// as prefix (e.g., {{{SomeTiddlerViewTemplate}}})
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.TaggedTemplateTweak= {major: 1, minor: 5, revision: 1, date: new Date(2009,1,6)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
// get default template from core
var coreTemplate=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);
// if the tiddler doesn't exist yet, return core result
var tiddler=store.getTiddler(title); if (!tiddler) return coreTemplate;
// split core template into theme prefix and template name
var theme="";
var template=coreTemplate;
var parts=template.split(config.textPrimitives.sectionSeparator);
if (parts[1]) { theme=parts[0]; template=parts[1]; }
else theme=config.options.txtTheme||""; // fallback if theme is not specified
theme+=config.textPrimitives.sectionSeparator;
// look for template whose prefix matches the *title* of this tiddler
if (!store.getTaggedTiddlers(title).length) { // if tiddler is not a tag
if (store.getTiddlerText(theme+title+template)) { return theme+title+template; } // theme##TitleTemplate
if (store.getTiddlerText(title+template)) { return title+template; } // TitleTemplate
}
// look for template whose prefix matches a *tag* on this tiddler (if any)
for (i=0; i<tiddler.tags.length; i++) {
var t=tiddler.tags[i]+template; // add tag prefix to template
var c=t.substr(0,1).toUpperCase()+t.substr(1); // capitalized for WikiWord title
if (store.getTiddlerText(theme+t)) { return theme+t; } // theme##tagTemplate
if (store.getTiddlerText(theme+c)) { return theme+c; } // theme##TagTemplate
if (store.getTiddlerText(t)) { return t; } // tagTemplate
if (store.getTiddlerText(c)) { return c; } // TagTemplate
}
// no matching tag OR title prefix... return core result
return coreTemplate;
}
//}}}
!Problem solved - Thank you very much Eric!!
Wikify-Plugin updated..
#<<newHere label:"NewHere">> (No problem)<br><br><br>
#{{{<<Newhere>>}}} fetched from [[studenttiddler|TstStudent#2]]" <- Click and see error message!
*{{{<<tiddler TstStudent#2>>}}}
**<<tiddler TstStudent#2>> But viewed from here it's ok??!! <br><br><br>
#{{{<<Newhere>>}}} fetched from [[teachertiddler|NewTsT]]" <- Click and see error message!
*{{{<<tiddler NewTsT>>}}}
**<<tiddler NewTsT>> But viewed from here it's looks allright??!!<br><br><br>
I presume that it's a customized ViewTemplate problem.
I've done sth in the [[Student-|ElevViewTemplate]] and [[TeacherViewTemplates|LærereViewTemplate]] - which is "breaking" NewHerePlugin.
It works fine in my "normal" ViewTemplate //(Which I have also tweaked a little)..//
It also works with the original shadow ViewTemplate. //(Rename ViewTemplate - to get it back)//
''Can you tell where I made an @@color(#ff0000):error@@??''
@@color(#009900)://Btw - could you also - //Please// - tell me how to get rid of the constantly shifting "permalink-addressshifting" which occurs every time I open a new tiddler??//@@
YS MÃ¥ns MÃ¥rtensson
<<tiddler ContactsFormTemplate>>
/***
|Name:|ToggleTagPlugin|
|Description:|Makes a checkbox which toggles a tag in a tiddler|
|Version:|3.1.0 ($Rev: 4907 $)|
|Date:|$Date: 2008-05-13 03:15:46 +1000 (Tue, 13 May 2008) $|
|Source:|http://mptw.tiddlyspot.com/#ToggleTagPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!!Usage
{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}
* TagName - the tag to be toggled, default value "checked"
* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler
* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'
(If a parameter is '.' then the default will be used)
* TouchMod flag - if non empty then touch the tiddlers mod date. Note, can set config.toggleTagAlwaysTouchModDate to always touch mod date
!!Examples
|Code|Description|Example|h
|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|
|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|
|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|
|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|
|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|
!!Notes
* If TiddlerName doesn't exist it will be silently created
* Set label to '-' to specify no label
* See also http://mgtd-alpha.tiddlyspot.com/#ToggleTag2
!!Known issues
* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing
* Should convert to use named params
***/
//{{{
if (config.toggleTagAlwaysTouchModDate == undefined) config.toggleTagAlwaysTouchModDate = false;
merge(config.macros,{
toggleTag: {
createIfRequired: true,
shortLabel: "[[%0]]",
longLabel: "[[%0]] [[%1]]",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var tiddlerTitle = tiddler ? tiddler.title : '';
var tag = (params[0] && params[0] != '.') ? params[0] : "checked";
var title = (params[1] && params[1] != '.') ? params[1] : tiddlerTitle;
var defaultLabel = (title == tiddlerTitle ? this.shortLabel : this.longLabel);
var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;
var touchMod = (params[3] && params[3] != '.') ? params[3] : "";
label = (label == '-' ? '' : label); // dash means no label
var theTiddler = (title == tiddlerTitle ? tiddler : store.getTiddler(title));
var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {
if (!store.tiddlerExists(title)) {
if (config.macros.toggleTag.createIfRequired) {
var content = store.getTiddlerText(title); // just in case it's a shadow
store.saveTiddler(title,title,content?content:"",config.options.txtUserName,new Date(),null);
}
else
return false;
}
if ((touchMod != "" || config.toggleTagAlwaysTouchModDate) && theTiddler)
theTiddler.modified = new Date();
store.setTiddlerTag(title,this.checked,tag);
return true;
});
}
}
});
//}}}
|~ViewToolbar| closeOthers closeTiddler +editTiddler > closeTiddler fields permalink > copyTiddler references deleteTiddler |
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
|~ElevViewToolbar| closeOthers closeTiddler +editTiddler > fields permalink > copyTiddler references deleteTiddler|
|~ElevEditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
<<back>>
<<tag Menu>>
<<history>>
<<forward>>
<<search>>
<<wikify "[[AdresseBog|%0]]" fuldenavn>>
<<newTiddler title: {{tiddler.fields.fuldenavn}} label: 'Ny Adressebog' tag: {{tiddler.title}} Adressebog text: {{store.getTiddlerText("AdresseTabs")}} label: 'Kontaktadresser'>>
<<newHere title:"Ny herfra">>
/***
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 = 'tstcase';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n")
});
//}}}
<<tiddler ContactsFormTemplate>>
first.name=first.name
last.name=last.name
email=email
other.email=other.email
business.email=business.email
webpage=webpage
phone=phone
mobile=mobile
address=address
city=city
state=state
postal=postal
country=country
company=company
job.title=job.title
business.phone=business.phone
business.mobile=business.mobile
business.fax=business.fax
business.address=business.address
business.city=business.city
business.state=business.state
business.postal=business.postal
business.country=business.country
business.webpage=business.webpage
ssn=ssn
birthday=birthday
anniversary=anniversary
children=children
notes=notes
/***
| Name|TwabPlugin|
| Author|Vincent ~DiBartolo ([[vdibart@tiddly-twab.com|mailto:vdibart@tiddly-twab.com]])|
| Version|2.1|
| Date|07/21/2008|
| Source|http://www.tiddly-twab.com/#TwabPlugin|
| License|BSD License - http://www.tiddly-twab.com/#TheBSDLicense|
| Requires|~TW2.x, [[DataTiddlerPlugin]], [[FormTiddlerPlugin]], [[InlineJavascriptPlugin]], [[PartTiddlerPlugin]], and any Tiddlers with the [[twab]] tag in the source file |
!Description
Elegant system for keeping your Address Book inside a TiddlyWiki document. Supports import and export of contacts via CSV data. Built-in support for Google, Yahoo, MSN, and Outlook CSV formats. Supports customized formats for those not built-in.
!History
* 21-Jul-08, version 2.1 - use Contact's first and last name in email link if it's present (Thanks to Lyall)
* 20-Feb-08, version 2.0 - import and export Google, Yahoo, MSN, Outlook, or custom CSV formats
* 29-Jun-07, version 1.1 - adding support for mailto:, http:, and map directions
* 20-Jun-07, version 1.0 - preparing for release, changed name to twab
* 19-Jun-07, version 0.4 - modified how new contacts are added
* 21-Nov-06, version 0.3 - changed name from ContactParserMacro to AddressBookMacro
* 10-Oct-06, version 0.2 - converted from regex parsing for title of contact Tiddler to JSON
* 09-Oct-06, version 0.1 - created file
!Example of Adding New Contact
Place the following code in any Tiddler:
{{{
<<twab>>
}}}
Which will result in: <<twab>>
You can add extra parameters to change the button's name as in:
{{{
<<twab press this button>>
}}}
Which will result in: <<twab press this button>>
See [[About:twab:Overview]] for more information.
!Example of Import
Place the following code in any Tiddler:
{{{
<<twab Import AddressBook>>
}}}
Which will result in: <<twab Import AddressBook>>
See [[About:twab:Import]] for more information.
!Example of Export
Place the following code in any Tiddler:
{{{
<<twab Export AddressBook>>
}}}
Which will result in: <<twab Export AddressBook>>
See [[About:twab:Export]] for more information.
! Generate Test Data for Import
Place the following code in any Tiddler:
{{{
<<twab ImportTest>>
}}}
Which will result in: <<twab ImportTest>>
See [[About:twab:Import]] for more information.
!Code
***/
//{{{
version.extensions.TwabMacro = {
major: 2,
minor: 0,
revision: 0,
date: new Date(2008,02,16),
source: "http://www.tiddly-twab.com"
};
config.macros.twab = {};
config.macros.twab.newButtonText = "Ny kontakt";
config.macros.twab.importButtonText = "importer kontakter";
config.macros.twab.exportButtonText = "eksporter kontakter";
config.macros.twab.preClean = true;
config.macros.twab.importTiddler = "TwabImporter";
config.macros.twab.exportTiddler = "TwabEksporter";
config.macros.twab.importTags = "Adressebog";
config.macros.twab.exportTags = "Adressebog";
config.macros.twab.fnameField = "fornavn";
config.macros.twab.lnameField = "efternavn";
config.macros.twab.mapTagPrefix = "format:";
config.macros.twab.skipFlag = "<skip>";
config.macros.twab.unmappedFlag = "ikke placeret";
config.macros.twab.handler = function (place, macroName, params) {
if( (params.length == 1) && (params[0] == "ImportTest") ){
//if they want to create an import test button
createTiddlyButton(place, "Populate " + config.macros.twab.importTiddler, "", this.testImport);
return;
} else if( (params.length >= 1) && (params[0] == "Import") ){
//any other params are interpreted as tags to be placed on imported tiddlers
if( params.length >= 2 ){
config.macros.twab.importTags = "";
for( var i=1; i<params.length; i++){
config.macros.twab.importTags += params[i] + " ";
}//for
}//if
//if they want to import data
createTiddlyButton(place, config.macros.twab.importButtonText, "", this.importContacts);
} else if( (params.length >= 1) && (params[0] == "Export") ){
//the first tag of the remainder is the one to use for exports
if( params.length >= 2 ){
config.macros.twab.exportTags = params[1];
}//if
//if they want to export data
createTiddlyButton(place, config.macros.twab.exportButtonText, "", this.exportContacts);
} else {
//assume want to create a new contact - any extra params are button name
var buttonText = "";
for( var i=0; i<params.length; i++){
buttonText += " " + params[i] + " ";
}//for
createTiddlyButton(place, ((buttonText == "") ? config.macros.twab.newButtonText : buttonText), "", this.newContact);
}//if-else ifs
}//function handler
//from: http://www.nicknettleton.com/zine/javascript/trim-a-string-in-javascript
config.macros.twab.trim = function(word) { return word.replace(/^\s+|\s+$/g, ''); }
//proxy that retrieves some data and sets null to empty string
config.macros.twab.getData = function(tiddlerName, fieldName){
var data = DataTiddler.getData(tiddlerName, fieldName);
if( data == null ){
data = "";
}//if
return data;
}//function getData
config.macros.twab.testImport = function(e){
var title = config.macros.twab.importTiddler;
var text = "first.name,last.name,job.title,webpage,phone,email\nPrincess,Leia,\"Leader, Rebels\",http://starwars.wikia.com/wiki/Leia_Organa,,leia@alderaan.com\nDarth,Vader,\"Sith Lord\",http://starwars.wikia.com/wiki/Darth_Vader,555-1212,darth@deathstar.com\nLuke,Skywalker,Jedi Master,http://starwars.wikia.com/wiki/Luke_Skywalker,,luke@tatooine.com";
store.saveTiddler(title, title, text, config.options.txtUserName);
story.displayTiddler(null, title, DEFAULT_VIEW_TEMPLATE);
return true;
}//function import
config.macros.twab.newContact = function(e){
var title = prompt("Skriv kontakts navn", "");
if( (title == null) || (title == "") ){
return;
}//if
store.saveTiddler(title, title, "<<tiddler ContactsFormTemplate>><data>{}</data>", config.options.txtUserName, new Date(), config.macros.twab.importTags);
story.displayTiddler(null, title, DEFAULT_VIEW_TEMPLATE);
}//function new
config.macros.twab.importContacts = function(e){
config.macros.twab.deleteAll();
config.macros.twab.parseAll( config.macros.twab.getImportedCSVText() );
alert("Kontakter er blevet importerede med succes.");
return true;
}//function importContacts
config.macros.twab.exportContacts = function(e){
var title = config.macros.twab.exportTiddler;
var mapping = config.macros.twab.getMapping(title, true);
store.saveTiddler(title, title, config.macros.twab.getExportedCSVText(mapping), config.options.txtUserName );
story.displayTiddler(null, title, DEFAULT_VIEW_TEMPLATE);
return true;
}//function exportContacts
config.macros.twab.deleteAll = function(){
if( !config.macros.twab.preClean ){
return;
}//if
//only remove tiddlers tagged with only first tag if contacts each get more than one
var tags = config.macros.twab.importTags.split(" ");
var tag = tags[0];
if( !confirm("Er du sikker på at du vil slette eksisterende tiddlere der er taggede med \"" + tag + "\"?") ){
return;
}//if
var contacts = store.getTaggedTiddlers(tag);
for( var i=0; i<contacts.length; i++ ){
store.removeTiddler( contacts[i].title );
}//for
}//function deleteAll
config.macros.twab.getImportedCSVText = function(){
return store.getTiddler(config.macros.twab.importTiddler).text;
}//function getImportedCSVText
config.macros.twab.getExportedCSVText = function(mapping){
var returnStr = "";
//get the mapped header columns
for( var i=0; i<mapping.length; i++ ){
if( mapping[i] && (mapping[i] != config.macros.twab.unmappedFlag) ){
var twabCol = mapping[i];
var mapCol = mapping[twabCol];
returnStr += '"' + mapCol + '",';
}//if
}//for
//get the unmapped header columns
var unmappedStr = mapping[config.macros.twab.unmappedFlag];
if( unmappedStr ){
var unmappedArr = unmappedStr.split(",");
for( var i=0; i<unmappedArr.length; i++ ){
returnStr += '"' + unmappedArr[i] + '",';
}//for
//strip off the last ","
returnStr = returnStr.substring(0, returnStr.length-1);
}//if
returnStr += "\n";
//get all contacts
var tags = config.macros.twab.exportTags.split(" ");
var contacts = store.getTaggedTiddlers( tags[0] );
for( var i=0; i<contacts.length; i++ ){
returnStr += config.macros.twab.exportContact(contacts[i], mapping) + "\n";
}//for
return returnStr;
}//function getExportedCSVText
config.macros.twab.parseAll = function (contactStr){
var rows = contactStr.split("\n");
if( rows.length < 2 ){
alert("Der er nødt til at være to eller flere rækker for at kunne parse kontakter.");
return;
}//if
var header = config.macros.twab.parseHeader(rows[0]);
if( header.length == 0 ){
return;
}//if
var contacts = new Array();
for( i=1; i<rows.length; i++){
contacts[ i-1 ] = config.macros.twab.parseContact(header, rows[i]);
}//for
//uncomment this to get contact-by-contact alerts
//config.macros.twab.debugAll(contacts);
config.macros.twab.addAll(contacts);
}//function parseAll
config.macros.twab.parseHeader = function(row){
var mappedHeader = new Array();
//get the raw data
var unmappedHeader = config.macros.twab.parseCSV(row);
//get the appropriate mapping
var mapping = config.macros.twab.getMapping(config.macros.twab.importTiddler, false);
//now convert the unmapped header to the mapped header
for( var i=0; i<unmappedHeader.length; i++ ){
var colName = unmappedHeader[i].replace(/ /g, ".").toLowerCase();
if( mapping[colName] ){
mappedHeader[i] = mapping[colName];
} else {
mappedHeader[i] = config.macros.twab.skipFlag;
}//if
//uncomment this to get field-by-field alerts from the header
//alert("Header field " + i + " is '" + mappedHeader[i] + "'");
}//for
return mappedHeader;
}//function parseHeader
config.macros.twab.getMapping = function(tiddlerName, isExport){
var mapTiddlerName = "";
if( store.getTiddler(tiddlerName) ){
//see if they've declared a mapping (preset or custom) by looking
//at a tag on the tiddler passed in
var tagStr = ""+store.getTiddler(tiddlerName).tags;
var tags = tagStr.split(',');
for( var i=0; i<tags.length; i++ ){
if( tags[i].indexOf( config.macros.twab.mapTagPrefix ) == 0 ){
mapTiddlerName = tags[i].replace(config.macros.twab.mapTagPrefix, "");
}//if
}//for
}//if
//parse the mapping Tiddler
var mapTiddler = config.macros.twab.getMappingTiddler(mapTiddlerName);
if( !mapTiddler ){
alert("Importer/Eksporter Format Tiddler " + mapTiddler + " findes ikke. kan ikke fortsætte.");
return new Array();
}//if
var mapText = ""+store.getTiddler(mapTiddler).text;
var mapArr = mapText.split("\n");
var mapping = new Array();
for( var i=0; i<mapArr.length; i++ ){
var rule = mapArr[i].split("=");
if( !rule || (rule.length < 2) ){
continue;
}//if
//uncomment this to see what mapping is being applied to your import file
//alert("Twab column '" + twabCol + "' is mapped to input tiddler column '" + mapCol + "'");
if( isExport ){
var twabCol = config.macros.twab.trim( rule[0] );
var mapCol = config.macros.twab.trim( rule[1] );
if( mapCol == config.macros.twab.skipFlag ){
continue;
}//inner if
mapping[twabCol] = mapCol;
mapping[i] = twabCol;
} else {
var twabCol = config.macros.twab.trim( rule[0].replace(/ /g, ".").toLowerCase() );
var mapCol = config.macros.twab.trim( rule[1].replace(/ /g, ".").toLowerCase() );
mapping[mapCol] = twabCol;
mapping[i] = mapCol;
}//outer if-else
}//for
return mapping;
}//function getMapping
config.macros.twab.getMappingTiddler = function(name){
var tiddlerName = "TwabDefaultFieldMap";
if( name == "google" ){
tiddlerName = "TwabGoogleFieldMap";
} else if( name == "yahoo" ){
tiddlerName = "TwabYahooFieldMap";
} else if( name == "msn" ){
tiddlerName = "TwabMSNFieldMap";
} else if( name == "outlook" ){
tiddlerName = "TwabOutlookFieldMap";
} else {
//see if a Tiddler by this name exists, if not use the default
if( (name != "default") && store.getTiddler(name) ){
tiddlerName = name;
} else {
tiddlerName = "TwabDefaultFieldMap";
}//inner if-else
}//outer if-else ifs
return tiddlerName;
}//function getMappingTiddler
config.macros.twab.parseCSV = function(row){
var scrubbed = new Array();
var fields = row.split(",");
for( var i=0; i<fields.length; i++){
//if starts with quote but doesn't end with a quote, likely had a comma in the middle
if( (fields[i].charAt(0) == '"') && (fields[i].charAt( fields[i].length-1) != '"') ){
//Hotmail bug: last contact doesn't have ending double-quote
if( i == (fields.length-1) ){
scrubbed[ scrubbed.length ] = fields[i].replace(/"/g, "");
continue;
}//if
var quoted = fields[i++];
if( !fields[i] ){
continue;
}//if
while( fields[i].charAt( fields[i].length-1 ) != '"' ){
quoted += "," + fields[i++];
}//while
quoted += "," + fields[i];
scrubbed[ scrubbed.length ] = quoted.replace(/"/g, "");
} else {
scrubbed[ scrubbed.length ] = fields[i].replace(/"/g, "");
}//if-else
}//for
return scrubbed;
}//function parseCSV
config.macros.twab.parseContact = function (header, row){
var returnStr = "";
var fields = config.macros.twab.parseCSV(row);
for( var i=0; i<fields.length; i++ ){
if( header[i] == config.macros.twab.skipFlag ){
continue;
} else if( fields[i] ){
returnStr += "\"" + header[i] + "\":\"" + fields[i] + "\",";
}//if-else
}//for
return returnStr.substr(0, returnStr.length-1);
}//function parseContact
//export a particular contact to a particular mapping
config.macros.twab.exportContact = function(contactTiddler, mapping){
var returnStr = "";
var text = contactTiddler.text;
//have to strip out FormTiddler stuff
text = text.replace(/<<tiddler ContactsFormTemplate>>/g, "");
text = text.replace(/<data>/g, "");
text = text.replace(/<\/data>/g, "");
text = text.replace(/\n/g, "");
//use JSON format to our advantage
var contact = eval( "("+text+")" );
for( var i=0; i<mapping.length; i++){
var twabCol = mapping[i];
if( !(twabCol) ||
!(mapping[twabCol]) ||
(twabCol == config.macros.twab.unmappedFlag) ||
(mapping[twabCol] == config.macros.twab.skipFlag)){
continue;
}//if
//Google hack - on export, "Name" should be "first.name" and "last.name" together.
//Know this because "first.name" is mapped to "Name" and "last.name" is not mapped
if( (twabCol == config.macros.twab.fnameField) && !mapping[config.macros.twab.lnameField] ){
returnStr += '"' + contact[config.macros.twab.fnameField] + " " + contact[config.macros.twab.lnameField] + '",'
} else if( contact[twabCol] ){
returnStr += '"' + contact[twabCol] + '",';
} else {
returnStr += ",";
}//if-else
}//for
//get the unmapped columns
var unmappedStr = mapping[config.macros.twab.unmappedFlag];
if( unmappedStr ){
var unmappedArr = unmappedStr.split(",");
for( var i=0; i<unmappedArr.length; i++ ){
returnStr += ",";
}//for
//strip out the last ","
returnStr = returnStr.substr(0, returnStr.length-1);
}//if
return returnStr.replace(/\n/g, "");
}//function exportContact
//add/overwrite existing contacts with the data parsed out of the import tiddler
config.macros.twab.addAll = function(contacts){
for( var i=0; i<contacts.length; i++ ){
if( !contacts[i] ){
continue;
}//if
var title = "";
//use JSON format to our advantage
var toEval = "({" + contacts[i] + "})";
var contact = eval(toEval);
if( contact[config.macros.twab.fnameField] ){
title += contact[config.macros.twab.fnameField];
}//inner if
if( contact[config.macros.twab.lnameField] ){
title += contact[config.macros.twab.lnameField];
}//inner if
if( title == "" ){
alert("kontakt mangler et navnefelt - kunne ikke blive tilføjet: \n" + contacts[i]);
continue;
}//inner if
//add it now
var text = config.macros.twab.toTiddlyFormat(contacts[i]);
store.saveTiddler(title, title, text, config.options.txtUserName, new Date(), config.macros.twab.importTags);
}//for
}//function addAll
config.macros.twab.toTiddlyFormat = function(contact){
var tpl = config.macros.twab.getContactTemplate();
return tpl.replace( config.macros.twab.getMacroName(), contact);
}//function toTiddlyFormat
config.macros.twab.getContactTemplate = function(){
var macroName = config.macros.twab.getMacroName();
return "<<tiddler ContactsFormTemplate>>\n<data>{" + macroName + "}</data>";
}//function getContactTemplate
config.macros.twab.getMacroName = function(){
return "#thisContact#";
}//function getMacroName
config.macros.twab.debugAll = function(contacts){
for( var i=0; i<contacts.length; i++ ){
//alert( contacts[i] );
alert( config.macros.twab.toTiddlyFormat(contacts[i]) );
}//for
}//function debugAll
config.macros.twab.populateLinks = function(place){
config.macros.twab.populateEmail(place, "email");
config.macros.twab.populateEmail(place, "other.email");
config.macros.twab.populateEmail(place, "business.email");
config.macros.twab.populateHref(place, "webpage");
config.macros.twab.populateMap(place, "home");
config.macros.twab.populateHref(place, "business.webpage");
config.macros.twab.populateMap(place, "business");
}//function populateLinks
config.macros.twab.populateEmail = function(place, fieldName){
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);
var element = document.getElementById("twab." + fieldName);
if( element ){
element.innerHTML = config.macros.twab.formatEmail(tiddlerName, fieldName);
}//if
}//function populateEmail
//Thanks to Udo for the idea for this solution and to Lyall for the code to use display name
config.macros.twab.formatEmail = function(tiddlerName, fieldName){
var returnStr = "";
var mailTo = config.macros.twab.getData(tiddlerName, fieldName);
var displayName = config.macros.twab.getData(tiddlerName, "first.name") + " " + config.macros.twab.getData(tiddlerName, "last.name");
if( mailTo != "" ){
if( displayName != "" ){
mailTo = displayName + "<" + mailTo + ">";
}//if
returnStr = "<a href=\"mailto:" + mailTo + "\" content=\"\">(email)</a>";
}//if
return returnStr;
}//function formatEmail
config.macros.twab.populateHref = function(place, fieldName){
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);
var element = document.getElementById("twab." + fieldName);
if( element ){
element.innerHTML = config.macros.twab.formatHref(tiddlerName, fieldName);
}//if
}//function populateHref
//Thanks to Udo for the idea for this solution
config.macros.twab.formatHref = function(tiddlerName, fieldName){
var returnStr = "";
var href = config.macros.twab.getData(tiddlerName, fieldName);
if( href != "" ){
if( href.indexOf("http") != 0 ){
href = "http://" + href;
}//inner if
returnStr = "<a href=\"" + href + "\" content=\"\" target=\"twab\">(visit)</a>";
}//if
return returnStr;
}//function formatHref
config.macros.twab.populateMap = function(place, fieldType){
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);
var element = document.getElementById("twab." + fieldType + ".map");
if( element ){
element.innerHTML = config.macros.twab.formatMap(tiddlerName, fieldType);
}//if
}//function populateHref
//Thanks to Udo for the idea for this solution
config.macros.twab.formatMap = function(tiddlerName, fieldType){
//hack for lack of planning of home versus business labels
if( fieldType == "business"){
fieldType += ".";
} else if( fieldType == "home" ){
fieldType = "";
}//if-else if
var returnStr = "";
var address = "";
if( DataTiddler.getData(tiddlerName, fieldType+"address") ){
address += DataTiddler.getData(tiddlerName, fieldType+"address") + " ";
}//if
if( DataTiddler.getData(tiddlerName, fieldType+"city") ){
address += DataTiddler.getData(tiddlerName, fieldType+"city") + " ";
}//if
if( DataTiddler.getData(tiddlerName, fieldType+"state") ){
address += DataTiddler.getData(tiddlerName, fieldType+"state") + " ";
}//if
if( DataTiddler.getData(tiddlerName, fieldType+"postal") ){
address += DataTiddler.getData(tiddlerName, fieldType+"postal") + " ";
}//if
if( address == "" ){
return "";
}//if
var href = "http://maps.google.com/maps?ie=UTF8&hl=en&q=" + address + "&f=q&sampleq=1";
returnStr = "<a href=\"" + href + "\" content=\"\" target=\"twab\">(map)</a>";
returnStr.replace(/ /g, "\+");
return returnStr;
}//function formatMap
//}}}
<part tab1form>
<<formTiddler TwabTabParts/tab1>>
<script>config.macros.twab.populateLinks(place);</script>
</part>
<part tab1>
<html>
<span style="font-family: Comic Sans MS;"> <span class="rolodex"> </span></span><span class="rolodex">
<table>
<tbody>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Fornavn:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="first.name" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Efternavn:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="last.name" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>eMail <mail:</b></span></td>
<td colspan="2"><span style="font-family: Comic Sans MS;"><input type="text" name="email" size="50" style="width: 100%;" /></span></td>
<td id="twab.email"><span style="font-family: Comic Sans MS;"> </span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Alt eMail <mail:</b></span></td>
<td colspan="2"><span style="font-family: Comic Sans MS;"><input type="text" name="other.email" size="50" style="width: 100%;" /></span></td>
<td id="twab.other.email"><span style="font-family: Comic Sans MS;"> </span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Job eMail<mail:</b></span></td>
<td colspan="2"><span style="font-family: Comic Sans MS;"><input type="text" name="business.email" size="50" style="width: 100%;" /></span></td>
<td id="twab.business.email"><span style="font-family: Comic Sans MS;"> </span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Hjemmeside:</b></span></td>
<td colspan="2"><span style="font-family: Comic Sans MS;"><input type="text" name="webpage" size="50" style="width: 100%;" /></span></td>
<td id="twab.webpage"><span style="font-family: Comic Sans MS;"> </span></td>
</tr>
</tbody>
</table>
</span>
</html>
</part>
<part tab2form>
<<formTiddler TwabTabParts/tab2>>
<script>config.macros.twab.populateLinks(place);</script>
</part>
<part tab2>
<html>
<span style="font-family: Comic Sans MS;"> <span class="rolodex"> </span></span><span class="rolodex">
<table>
<tbody>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Telefon:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="phone" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Mobil:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="mobile" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td valign="top" align="right"><span style="font-family: Comic Sans MS;"><b>Adresse:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><textarea name="address" rows="2" cols="40" style="width: 100%;"></textarea></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>By:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="city" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Landsdel:</b></span></td>
<td><span style="font-family: Comic Sans MS;"><input type="text" name="state" size="5" /></span></td>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Postnummer:</b></span></td>
<td><span style="font-family: Comic Sans MS;"><input type="text" name="postal" size="5" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Land:</b></span></td>
<td colspan="2"><span style="font-family: Comic Sans MS;"><input type="text" name="home.country" size="50" style="width: 100%;" /></span></td>
<td id="twab.home.map"><span style="font-family: Comic Sans MS;"> </span></td>
</tr>
</tbody>
</table>
</span>
</html>
</part>
<part tab3form>
<<formTiddler TwabTabParts/tab3>>
<script>config.macros.twab.populateLinks(place);</script>
</part>
<part tab3>
<html>
<span style="font-family: Comic Sans MS;"> <span class="rolodex"> </span></span><span class="rolodex">
<table>
<tbody>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Arbejde:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="company" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>JobTitel:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="job.title" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Arbejdstelefon:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="business.phone" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Arbejdsmobil:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="business.mobile" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Faxnummer:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="business.fax" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td valign="top" align="right"><span style="font-family: Comic Sans MS;"><b>Arbejdsadresse:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><textarea name="business.address" rows="2" cols="40" style="width: 100%;"></textarea></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Job-By:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="business.city" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Job-Landsdel:</b></span></td>
<td><span style="font-family: Comic Sans MS;"><input type="text" name="business.state" size="5" /></span></td>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Job-Postnummer:</b></span></td>
<td><span style="font-family: Comic Sans MS;"><input type="text" name="business.postal" size="5" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Job-Land:</b></span></td>
<td colspan="2"><span style="font-family: Comic Sans MS;"><input type="text" name="business.country" size="50" style="width: 100%;" /></span></td>
<td id="twab.business.map"><span style="font-family: Comic Sans MS;"> </span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Hjemmeside:</b></span></td>
<td colspan="2"><span style="font-family: Comic Sans MS;"><input type="text" name="business-webpage" size="50" style="width: 100%;" /></span></td>
<td id="twab.business.webpage"><span style="font-family: Comic Sans MS;"> </span></td>
</tr>
</tbody>
</table>
</span>
</html>
</part>
<part tab4form>
<<formTiddler TwabTabParts/tab4>>
<script>config.macros.twab.populateLinks(place);</script>
</part>
<part tab4>
<html>
<span style="font-family: Comic Sans MS;"> <span class="rolodex"> </span></span><span class="rolodex">
<table>
<tbody>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Cpr:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="ssn" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Fødselsdag:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="birthday" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Mærkedag:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="anniversary" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Børn:</b></span></td>
<td colspan="3"><span style="font-family: Comic Sans MS;"><input type="text" name="children" size="50" style="width: 100%;" /></span></td>
</tr>
<tr>
<td align="right"><span style="font-family: Comic Sans MS;"><b>Noter:</b></span></td>
<td><span style="font-family: Comic Sans MS;"><textarea name="notes" rows="4" cols="40" style="width: 100%;"></textarea></span></td>
</tr>
</tbody>
</table>
</span>
</html>
</part>
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 29/03/2009 16:13:36 | YourName | [[/|http://tstcase.tiddlyspot.com/#TestStudent-]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . | ok |
| 29/03/2009 16:16:06 | YourName | [[/|http://tstcase.tiddlyspot.com/#L%C3%A6rere]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 29/03/2009 16:28:47 | YourName | [[index.html|http://tstcase.tiddlyspot.com/index.html#ElevViewTemplate]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 29/03/2009 16:32:42 | YourName | [[index.html|http://tstcase.tiddlyspot.com/index.html#ElevViewTemplate]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 29/03/2009 16:42:54 | YourName | [[index.html|http://tstcase.tiddlyspot.com/index.html#ElevViewTemplate]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 29/03/2009 16:48:53 | YourName | [[index.html|http://tstcase.tiddlyspot.com/index.html#ViewTemplate]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 29/03/2009 16:49:01 | YourName | [[index.html|http://tstcase.tiddlyspot.com/index.html#ViewTemplate]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 29/03/2009 16:58:11 | YourName | [[index.html|http://tstcase.tiddlyspot.com/index.html#TestStudent%231]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 29/03/2009 20:00:37 | YourName | [[/|http://tstcase.tiddlyspot.com/#WikifyPlugin]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
| 30/03/2009 11:01:24 | YourName | [[index.html|http://tstcase.tiddlyspot.com/index.html#TestCase]] | [[store.cgi|http://tstcase.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tstcase.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></span><span macro='email to:"humamamm@gmail.com" permalink:"true"'></</span></div>
<div macro="hideWhenTaggedAny noTitle">
<div class='title' macro='view title'></div>
</div>
<div macro="hideWhenTaggedAny systemTool systemList Kl">
<div class='tagged' macro='tags'></div>
</div>
<div class='tagClear'></div>
<div class='viewer' macro='view text wikified'></div>
<div macro="showWhenTagged [[systemList]]">
<div class='viewer' macro="listByTag '' modified ''"></div>
</div>
<div class='tagClear'></div>
<!--}}}-->
/***
|''Name:''|WikiBar|
|''Version:''|2.0.0 beta3|
|''Source:''|[[AiddlyWiki|http://aiddlywiki.sourceforge.net]]|
|''Author:''|[[Arphen Lin|mailto:arphenlin@gmail.com]]|
|''Type:''|toolbar macro command extension|
|''Required:''|TiddlyWiki 2.0.0 beta6|
!Description
WikiBar is a toolbar that gives access to most of TiddlyWiki's formatting features with a few clicks. It's a handy tool for people who are not familiar with TiddlyWiki syntax.
Besides, with WikiBar-addons, users can extend the power of WikiBar.
!Support browser
*Firefox 1.5
!Revision history
*v2.0.0 beta3 (2005/12/30)
** remove macros (replaced by TWMacro addon)
** add wikibar command in toolbar automatically
** rename DOIT to HANDLER
** rename TIP to TOOLTIP
*v2.0.0 beta2 (2005/12/21)
** re-design Wikibar addon framework
*v2.0.0 beta1 (2005/12/14)
** Note:
*** WikiBarPlugin is renamed to WikiBar
** New Features:
*** support TiddlyWiki 2.0.0 template mechanism
*** new wikibar data structure
*** new wikibar-addon framework for developers
**** support dynamic popup menu generator
*** support most new macros added in TiddlyWiki 2.0.0
*** multi-level popup menu
*** fix wikibar tab stop
*** remove paletteSelector
** Known Bugs:
*** popup-menu and color-picker can't be closed correctly
*** some macros can't be displayed correctly in previewer
*** text in previewer will be displayed italic
*v1.2.0 (2005/11/21)
**New Features:
***User defined color palettes supported
####Get color palettes from [[ColorZilla Palettes|http://www.iosart.com/firefox/colorzilla/palettes.html]].
####Save the palette file(*.gpl) as a new tiddler and tag it with 'ColorPalettes', then you can use it in WikiBar.
***WikiBar style sheet supported
***Click on document to close current colorPicker, paletteSelector or aboutWikibar
*v1.1.1 (2005/11/03)
**Bugs fixed:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.1.0 (2005/11/01)
**Bugs fixed:
***WikiBar overruns (reported by by GeoffS <gslocock@yahoo.co.uk>)
**New features:
***Insert a color code at the cursor. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Enable gradient macro. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Insert tiddler comment tags {{{/% ... %/}}}. (new feature supported by TiddlyWiki 1.2.37)
***Insert DateFormatString for {{{<<today>>}}} macro. (new feature supported by TiddlyWiki 1.2.37)
**Enhanced:
***Allow optional parameters in syntax.
**Bugs:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.0.0 (2005/10/30)
**Initial release
!Code
***/
//{{{
config.macros.wikibar = {major: 2, minor: 0, revision: 0, beta: 3, date: new Date(2005,12,30)};
config.macros.wikibar.handler = function(place,macroName,params,wikifier,paramString,tiddler){
if(!(tiddler instanceof Tiddler)) {return;}
story.setDirty(tiddler.title,true);
place.id = 'wikibar'+tiddler.title;
place.className = 'toolbar wikibar';
};
function wikibar_install(){
config.commands.wikibar = {
text: 'wikibar',
tooltip: 'wikibar on/off',
handler: function(e,src,title) {
if(!e){ e = window.event; }
var theButton = resolveTarget(e);
theButton.id = 'wikibarButton'+title;
wikibarPopup.remove();
wikibar_installAddons(theButton, title);
wikibar_createWikibar(title);
return(false);
}
};
config.shadowTiddlers['EditTemplate'] = wikibar_addWikibarCommand(config.shadowTiddlers['EditTemplate']);
var tiddler = store.getTiddler('EditTemplate');
if(tiddler){
tiddler.text = wikibar_addWikibarCommand(tiddler.text);
}
}
function wikibar_installAddons(theButton, title){
var tiddlers = store.getTaggedTiddlers('wikibarAddons');
if(!tiddlers) { return; }
theButton.addons=[];
for(var i=0; i<tiddlers.length; i++){
try{
eval(tiddlers[i].text);
try{
wikibar_addonInstall(title);
wikibar_addonInstall = null;
theButton.addons.push({ok:true, name:tiddlers[i].title});
}catch(ex){
theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
}
}catch(ex){
theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
}
}
}
function wikibar_addWikibarCommand(tiddlerText){
var div = document.createElement('div');
div.style.display = 'none';
div.innerHTML = tiddlerText;
for(var i=0; i<div.childNodes.length; i++){
var o=div.childNodes[i];
if(o.tagName==='DIV'){
if(o.className=='toolbar'){
var macroText = o.getAttribute('macro').trim();
if(macroText.search('wikibar')<=0){
macroText += ' wikibar';
o.setAttribute('macro', macroText);
}
break;
}
}
}
return div.innerHTML.replace(/\"/g, "\'");
}
function wikibar_processSyntaxParams(theSyntax, params){
try{
var pcr = 'AplWikibarPcr';
var rx=null;
var allParams=null;
if(params){
if(typeof(params)=='object'){
for(var i=0; i<params.length; i++){
if(params[i]){
params[i] = params[i].replace(new RegExp('%','g'), pcr).trim();
rx = '(\\[%'+(i+1)+'\\])' + '|' + '(%'+(i+1)+')';
theSyntax = theSyntax.replace(new RegExp(rx,'g'), params[i] );
}
}
allParams = params.join(' ').trim();
}else{
allParams = params.replace(new RegExp('%','g'), pcr).trim();
rx = /(\[%1{1}\])|(%1{1})/g;
theSyntax = theSyntax.replace(rx, allParams);
}
}
if(allParams){
theSyntax = theSyntax.replace(new RegExp('%N{1}','g'), allParams);
}
rx=/\[%(([1-9]{1,}[0-9]{0,})|(N{1}))\]/g;
theSyntax = theSyntax.replace(rx, '');
rx=/%(([1-9]{1,}[0-9]{0,})|(N{1}))/g;
if( theSyntax.match(rx) ){
throw 'Not enough parameters! ' + theSyntax;
}
theSyntax=theSyntax.replace(new RegExp(pcr,'g'), '%');
return theSyntax;
} catch(ex){
return null;
}
}
function wikibar_resolveEditItem(tiddlerWrapper, itemName){
if(tiddlerWrapper.hasChildNodes()){
var c=tiddlerWrapper.childNodes;
for(var i=0; i<c.length; i++){
var txt=wikibar_resolveEditItem(c[i], itemName);
if(!txt){
continue;
}else{
return txt;
}
}
}
return ((tiddlerWrapper.getAttribute && tiddlerWrapper.getAttribute('edit')==itemName)? tiddlerWrapper : null);
}
function wikibar_resolveEditItemValue(tiddlerWrapper, itemName){
var o = wikibar_resolveEditItem(tiddlerWrapper, itemName);
return (o? o.value.replace(/\r/mg,'') : null);
}
function wikibar_resolveTiddlerEditorWrapper(obj){
if(obj.id=='tiddlerDisplay'){return null;}
if((obj.getAttribute && obj.getAttribute('macro')=='edit text')){return obj;}
return wikibar_resolveTiddlerEditorWrapper(obj.parentNode);
}
function wikibar_resolveTiddlerEditor(obj){
if(obj.hasChildNodes()){
var c = obj.childNodes;
for(var i=0; i<c.length; i++){
var o=wikibar_resolveTiddlerEditor(c[i]);
if(o){ return o;}
}
}
return ((obj.getAttribute && obj.getAttribute('edit')=='text')? obj : null);
}
function wikibar_resolveTargetButton(obj){
if(obj.id && obj.id.substring(0,7)=='wikibar'){ return null; }
if(obj.tiddlerTitle){
return obj;
}else{
return wikibar_resolveTargetButton(obj.parentNode);
}
}
function wikibar_isValidMenuItem(tool){
if(!tool){ return false; }
if(tool.TYPE=='MENU' || tool.TYPE=='MAIN_MENU'){
for(var key in tool){
if(key.substring(0,8)=='DYNAITEM'){ return true; }
if(wikibar_isValidMenuItem(tool[key])){ return true; }
}
return false;
}else{
return (tool.HANDLER? true : false);
}
}
function wikibar_editFormat(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByWord(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){return;}
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
if(!( fullText.charAt(ss-1).match(/\W/gi) || fullText.charAt(ss).match(/\W/gi) )){
var m = frontText.match(/\W/gi);
if(m){
ss = frontText.lastIndexOf(m[m.length-1])+1;
}
else{
ss = 0;
}
m = endText.match(/\W/gi);
if(m){
se += endText.indexOf(m[0]);
}
else{
se = fullText.length;
}
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
selText = fullText.substring(ss,se);
}
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByCursor(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByLine(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
if(this.byBlock){
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
else{
se = ss;
}
}
if(ss===0 && (se===0 || se == fullText.length) ){
var m=fullText.match(/(\n|\r)/g);
if(m){
se = fullText.indexOf(m[0]);
}else{
se = fullText.length;
}
selText = fullText.substring(0, se);
endText = fullText.substring(se, fullText.length);
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
m = frontText.match(/(\n|\r)/g);
if(m){
ss = frontText.lastIndexOf(m[m.length-1])+1;
}
else{
ss = 0;
}
m = endText.match(/(\n|\r)/g);
if(m){
se += endText.indexOf(m[0]);
}
else{
se = fullText.length;
}
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
if(this.byBlock){
if( (frontText.charAt(frontText.length-1)!='\n') && ss>0 ){
repText = '\n' + repText;
}
if( (endText.charAt(0)!='\n') || se==fullText.length){
repText += '\n';
}
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByTableCell(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(ss===0 || ss==fullText.length){
throw 'not valid cell!';
}
se=ss;
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
i=frontText.lastIndexOf('\n');
j=frontText.lastIndexOf('|');
if(i>j || j<0){
throw 'not valid cell!';
}
ss = j+1;
i=endText.indexOf('\n');
j=endText.indexOf('|');
if(i<j || j<0){
throw 'not valid cell!';
}
se += j;
frontText = fullText.substring(0, ss-1);
selText = fullText.substring(ss,se);
endText = fullText.substring(se+1, fullText.length);
if(this.key.substring(0,5)=='align'){
selText = selText.trim();
if( selText=='>' || selText=='~' || selText.substring(0,8)=='bgcolor(') {return; }
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length - 2;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editSelectAll(param){
var editor = param.button.editor;
editor.selectionStart = 0;
editor.selectionEnd = editor.value.length;
editor.scrollTop = 0;
editor.focus();
}
function wikibar_doPreview(param){
var theButton = param.button;
var editor = param.button.editor;
var wikibar = theButton.parentNode;
if(!wikibar) { return; }
title = theButton.tiddlerTitle;
var editorWrapper = wikibar_resolveTiddlerEditorWrapper(editor);
var tiddlerWrapper = editorWrapper.parentNode;
var previewer = document.getElementById('previewer'+title);
if(previewer){
previewer.parentNode.removeChild(previewer);
editorWrapper.style.display = 'block';
visible=true;
}else{
previewer = document.createElement('div');
previewer.id = 'previewer'+title;
previewer.className = 'viewer previewer';
previewer.style.height = (editor.offsetHeight) + 'px';
wikify(editor.value, previewer);
tiddlerWrapper.insertBefore(previewer, editorWrapper);
editorWrapper.style.display = 'none';
visible=false;
}
var pv=null;
for(var i=0; i<wikibar.childNodes.length; i++){
try{
var btn = wikibar.childNodes[i];
if(btn.toolItem.key == 'preview'){ pv=btn; }
if(btn.toolItem.key != 'preview'){
btn.style.display = visible ? '': 'none';
}
}catch(ex){}
}
if(!pv) { return; }
if(visible){
pv.innerHTML = '<font face=\"verdana\">∞</font>';
pv.title = 'preview current tiddler';
}
else{
pv.innerHTML = '<font face=\"verdana\">←</font>';
pv.title = 'back to editor';
}
}
function wikibar_doListAddons(param){
clearMessage();
var title = param.button.tiddlerTitle;
var wikibarButton = document.getElementById('wikibarButton'+title);
var ok=0, fail=0;
for(var i=0; i<wikibarButton.addons.length; i++){
var addon=wikibarButton.addons[i];
if(addon.ok){
displayMessage('[ o ] '+addon.name);
ok++;
}
else{
displayMessage('[ x ] '+addon.name + ': ' + addon.error);
fail++;
}
}
displayMessage('---------------------------------');
displayMessage(ok + ' ok ; ' + fail + ' failed');
}
function wikibar_getColorCode(param){
var cbOnPickColor = function(colorCode, param){
param.params = colorCode;
param.button.toolItem.doMore(param);
};
wikibarColorTool.openColorPicker(param.button, cbOnPickColor, param);
}
function wikibar_getLinkUrl(param){
var url= prompt('Please enter the link target', (this.param? this.param : ''));
if (url && url.trim().length>0){
param.params = url;
this.doMore(param);
}
}
function wikibar_getTableRowCol(param){
var rc= prompt('Please enter (rows x cols) of the table', '2 x 3');
if (!rc || (rc.trim()).length<=0){ return; }
var arr = rc.toUpperCase().split('X');
if(arr.length != 2) { return; }
for(var i=0; i<arr.length; i++){
if(isNaN(arr[i].trim())) { return; }
}
var rows = parseInt(arr[0].trim(), 10);
var cols = parseInt(arr[1].trim(), 10);
var txtTable='';
for(var r=0; r<rows; r++){
for(var c=0; c<=cols; c++){
if(c===0){
txtTable += '|';
}else{
txtTable += ' |';
}
}
txtTable += '\n';
}
if(txtTable.trim().length>0){
param.params = txtTable.trim();
this.doMore(param);
}
}
function wikibar_getMacroParam(param){
var p = prompt('Please enter the parameters of macro \"' + this.key + '\":' +
'\nSyntax: ' + this.syntax +
'\n\nNote: '+
'\n%1,%2,... - parameter needed'+
'\n[%1] - optional parameter'+
'\n%N - more than one parameter(1~n)'+
'\n[%N] - any number of parameters(0~n)'+
'\n\nPS:'+
'\n1. Parameters should be seperated with space character'+
'\n2. Use \" to wrap the parameter that includes space character, ex: \"hello world\"'+
'\n3. Input the word(null) for the optional parameter ignored',
(this.param? this.param : '') );
if(!p) { return; }
p=p.readMacroParams();
for(var i=0; i<p.length; i++){
var s=p[i].trim();
if(s.indexOf(' ')>0){ p[i]="'"+s+"'"; }
if(s.toLowerCase()=='null'){ p[i]=null; }
}
param.params = p;
this.doMore(param);
}
function wikibar_getMorePalette(unused){
clearMessage();
displayMessage('Get more color palettes(*.gpl) from ColorZilla Palettes site', 'http:\/\/www.iosart.com/firefox/colorzilla/palettes.html');
displayMessage('Save it as a new tiddler with \"ColorPalettes\" tag');
}
function wikibar_createWikibar(title){
var theWikibar = document.getElementById('wikibar' + title);
if(theWikibar){
if(theWikibar.hasChildNodes()){
theWikibar.style.display = (theWikibar.style.display=='block'? 'none':'block');
return;
}
}
var tiddlerWrapper = document.getElementById('tiddler'+title);
var theTextarea = wikibar_resolveTiddlerEditor(tiddlerWrapper);
if(!theTextarea){
clearMessage();
displayMessage('WikiBar only works in tiddler edit mode now');
return;
}else{
if(!theTextarea.id){ theTextarea.id = 'editor'+title; }
if(!theTextarea.parentNode.id){ theTextarea.parentNode.id='editorWrapper'+title; }
}
if(theWikibar){
theWikibar = document.getElementById('wikibar'+title);
}else{
var editorWrapper = wikibar_resolveTiddlerEditorWrapper(theTextarea);
theWikibar = createTiddlyElement(tiddlerWrapper, 'div', 'wikibar'+title, 'toolbar');
addClass(theWikibar, 'wikibar');
var previewer = document.getElementById('previewer'+title);
if(previewer){
tiddlerWrapper.insertBefore(theWikibar, previewer);
}else{
tiddlerWrapper.insertBefore(theWikibar, editorWrapper);
}
}
wikibar_createMenu(theWikibar,wikibarStore,title,theTextarea);
if(config.options['chkWikibarSetEditorHeight'] && config.options['txtWikibarEditorRows']){
theTextarea.rows = config.options['txtWikibarEditorRows'];
}
setStylesheet(
'.wikibar{text-align:left;visibility:visible;margin:2px;padding:1px;}.previewer{overflow:auto;display:block;border:1px solid;}#colorPicker{position:absolute;display:none;z-index:10;margin:0px;padding:0px;}#colorPicker table{margin:0px;padding:0px;border:2px solid #000;border-spacing:0px;border-collapse:collapse;}#colorPicker td{margin:0px;padding:0px;border:1px solid;font-size:11px;text-align:center;cursor:auto;}#colorPicker .header{background-color:#fff;}#colorPicker .button{background-color:#fff;cursor:pointer;cursor:hand;}#colorPicker .button:hover{padding-top:3px;padding-bottom:3px;color:#fff;background-color:#136;}#colorPicker .cell{padding:4px;font-size:7px;cursor:crosshair;}#colorPicker .cell:hover{padding:10px;}.wikibarPopup{position:absolute;z-index:10;border:1px solid #014;color:#014;background-color:#cef;}.wikibarPopup table{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;}.wikibarPopup .button:hover{color:#eee;background-color:#014;}.wikibarPopup .disabled{color:#888;}.wikibarPopup .disabled:hover{color:#888;background-color:#cef;}.wikibarPopup tr .seperator hr{margin:0;padding:0;background-color:#cef;width:100%;border:0;border-top:1px dashed #014;}.wikibarPopup tr .icon{font-family:verdana;font-weight:bolder;}.wikibarPopup tr .marker{font-family:verdana;font-weight:bolder;}.wikibarPopup td{font-size:0.9em;padding:2px;}.wikibarPopup input{border:0;border-bottom:1px solid #014;margin:0;padding:0;font-family:arial;font-size:100%;background-color:#fff;}',
'WikiBarStyleSheet');
}
function wikibar_createMenu(place,toolset,title,editor){
if(!wikibar_isValidMenuItem(toolset)){return;}
if(!(toolset.TYPE=='MAIN_MENU' || toolset.TYPE=='MENU')){ return; }
for(var key in toolset){
if(key.substring(0,9)=='SEPERATOR'){
wikibar_createMenuSeperator(place);
continue;
}
if(key.substring(0,8)=='DYNAITEM'){
var dynaTools = toolset[key](title,editor);
if(dynaTools.TYPE && dynaTools.TYPE=='MENU'){
wikibar_createMenuItem(place,dynaTools,null,editor,title);
}else{
dynaTools.TYPE = 'MENU';
wikibar_createMenu(place, dynaTools, title, editor);
}
continue;
}
if((toolset[key].TYPE!='MENU' && toolset[key].TYPE!='MAIN_MENU') && !toolset[key].HANDLER){continue;}
wikibar_createMenuItem(place,toolset,key,editor,title);
}
}
function wikibar_createMenuItem(place,toolset,key,editor,title){
if(!key){
var tool = toolset;
}else{
tool = toolset[key];
tool.key = key;
}
if(!wikibar_isValidMenuItem(tool)){return;}
var toolIsOnMainMenu = (toolset.TYPE=='MAIN_MENU');
var toolIsMenu = (tool.TYPE=='MENU');
var theButton;
if(toolIsOnMainMenu){
theButton = createTiddlyButton(
place,
'',
(tool.TOOLTIP? tool.TOOLTIP : ''),
(toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem),
'button');
theButton.innerHTML = (tool.CAPTION? tool.CAPTION : key);
theButton.isOnMainMenu = true;
addClass(theButton, (toolIsMenu? 'menu' : 'item'));
place.appendChild( document.createTextNode('\n') );
if(!toolIsMenu){
if(config.options['chkWikibarPopmenuOnMouseOver']){
theButton.onmouseover = function(e){ wikibarPopup.remove(); };
}
}
}else{
theButton=createTiddlyElement(place, 'tr',key,'button');
theButton.title = (tool.TOOLTIP? tool.TOOLTIP : '');
theButton.onclick = (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem);
var tdL = createTiddlyElement(theButton, 'td','','marker');
var td = createTiddlyElement(theButton, 'td');
var tdR = createTiddlyElement(theButton, 'td','','marker');
td.innerHTML = (tool.CAPTION? tool.CAPTION : key);
if(toolIsMenu){
tdR.innerHTML=' ›';
}
if(tool.SELECTED){
tdL.innerHTML = '√ ';
addClass(theButton, 'selected');
}
if(tool.DISABLED){
addClass(theButton, 'disabled');
}
}
theButton.tiddlerTitle = title;
theButton.toolItem = tool;
theButton.editor = editor;
theButton.tabIndex = 999;
if(toolIsMenu){
if(config.options['chkWikibarPopmenuOnMouseOver']){
theButton.onmouseover = wikibar_onClickMenuItem;
}
}
}
function wikibar_createMenuSeperator(place){
if(place.id.substring(0,7)=='wikibar') { return; }
var onclickSeperator=function(e){
if(!e){ e = window.event; }
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return(false);
};
var theButton=createTiddlyElement(place,'tr','','seperator');
var td = createTiddlyElement(theButton, 'td','','seperator');
td.colSpan=3;
theButton.onclick=onclickSeperator;
td.innerHTML = '<hr>';
}
function wikibar_genWikibarAbout(){
var toolset={};
toolset.version = {
CAPTION: '<center>WikiBar ' +
config.macros.wikibar.major + '.' +
config.macros.wikibar.minor + '.' +
config.macros.wikibar.revision +
(config.macros.wikibar.beta? ' beta '+config.macros.wikibar.beta : '') +
'</center>',
HANDLER: function(){}
};
toolset.SEPERATOR = {};
toolset.author = {
CAPTION: '<center>Arphen Lin<br>arphenlin@gmail.com</center>',
TOOLTIP: 'send mail to the author',
HANDLER: function(){ window.open('mailto:arphenlin@gmail.com'); }
};
toolset.website = {
CAPTION: '<center>aiddlywiki.sourceforge.net</center>',
TOOLTIP: 'go to the web site of WikiBar',
HANDLER: function(){ window.open('http:\/\/aiddlywiki.sourceforge.net/'); }
};
return toolset;
}
function wikibar_genWikibarOptions(title, editor){
var toolset={};
toolset.popOnMouseOver = {
CAPTION:'popup menu on mouse over',
SELECTED: config.options['chkWikibarPopmenuOnMouseOver'],
HANDLER: function(param){
config.options['chkWikibarPopmenuOnMouseOver'] = !config.options['chkWikibarPopmenuOnMouseOver'];
saveOptionCookie('chkWikibarPopmenuOnMouseOver');
var title = param.button.tiddlerTitle;
var wikibar = document.getElementById('wikibar'+title);
if(wikibar){ wikibar.parentNode.removeChild(wikibar); }
wikibar_createWikibar(title);
}
};
toolset.setEditorSize = {
CAPTION:'set editor height: <input id=\"txtWikibarEditorRows\" type=text size=1 MAXLENGTH=3 value=\"' +
(config.options['txtWikibarEditorRows']? config.options['txtWikibarEditorRows']:editor.rows) + '\"> ok',
HANDLER: function(param){
var input = document.getElementById('txtWikibarEditorRows');
if(input){
var rows = parseInt(input.value, 10);
if(!isNaN(rows)){
var editor = param.button.editor;
editor.rows = rows;
}else{
rows=config.maxEditRows;
}
config.options['txtWikibarEditorRows'] = rows;
saveOptionCookie('txtWikibarEditorRows');
config.maxEditRows = rows;
}
}
};
toolset.setEditorSizeOnLoadingWikibar = {
CAPTION:'set editor height on loading wikibar',
SELECTED: config.options['chkWikibarSetEditorHeight'],
HANDLER: function(param){
config.options['chkWikibarSetEditorHeight'] = !config.options['chkWikibarSetEditorHeight'];
saveOptionCookie('chkWikibarSetEditorHeight');
if(config.options['chkWikibarSetEditorHeight']){
var rows = config.options['txtWikibarEditorRows'];
if(!isNaN(rows)){ rows = 15; }
var editor = param.button.editor;
editor.rows = rows;
config.options['txtWikibarEditorRows'] = rows;
saveOptionCookie('txtWikibarEditorRows');
}
}
};
toolset.SEPERATOR = {};
toolset.update = {
CAPTION: 'check for updates',
DISABLED: true,
HANDLER: function(){}
};
return toolset;
}
function wikibar_genPaletteSelector(){
try{
var cpTiddlers = store.getTaggedTiddlers('ColorPalettes');
if(!cpTiddlers) { return; }
var palettes=[];
palettes.push(wikibarColorTool.defaultPaletteName);
for(var i=0; i<cpTiddlers.length; i++){
palettes.push(cpTiddlers[i].title.trim());
}
var toolset={};
for(i=0; i<palettes.length; i++){
toolset[palettes[i]] = {
TOOLTIP: palettes[i],
SELECTED: (palettes[i]==wikibarColorTool.paletteName),
HANDLER: wikibar_doSelectPalette
};
}
return toolset;
}catch(ex){ return null; }
}
function wikibar_onClickItem(e){
if(!e){ e = window.event; }
var theTarget = resolveTarget(e);
if(theTarget.tagName=='INPUT'){
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return;
}
var theButton = wikibar_resolveTargetButton(theTarget);
if(!theButton){ return(false); }
var o = theButton.toolItem;
if(!o) { return; }
var param = {
event: e,
button: theButton
};
if(o.HANDLER){ o.HANDLER(param); }
if(o.DISABLED){
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
}
return(false);
}
function wikibar_onClickMenuItem(e){
if(!e){ e = window.event; }
var theButton = wikibar_resolveTargetButton(resolveTarget(e));
if(!theButton){ return(false); }
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
var title = theButton.tiddlerTitle;
var editor = theButton.editor;
var tool = theButton.toolItem;
if(!tool) { return; }
var popup = wikibarPopup.create(this);
if(popup){
wikibar_createMenu(popup,tool,title,editor);
if(!popup.hasChildNodes()){
wikibarPopup.remove();
}else{
wikibarPopup.show(popup, false);
}
}
return(false);
}
var wikibarColorTool = {
defaultPaletteName : 'default',
defaultColumns : 16,
defaultPalette : [
'#FFF','#DDD','#CCC','#BBB','#AAA','#999','#666','#333','#111','#000','#FC0','#F90','#F60','#F30','#C30','#C03',
'#9C0','#9D0','#9E0','#E90','#D90','#C90','#FC3','#FC6','#F96','#F63','#600','#900','#C00','#F00','#F36','#F03',
'#CF0','#CF3','#330','#660','#990','#CC0','#FF0','#C93','#C63','#300','#933','#C33','#F33','#C36','#F69','#F06',
'#9F0','#CF6','#9C3','#663','#993','#CC3','#FF3','#960','#930','#633','#C66','#F66','#903','#C39','#F6C','#F09',
'#6F0','#9F6','#6C3','#690','#996','#CC6','#FF6','#963','#630','#966','#F99','#F39','#C06','#906','#F3C','#F0C',
'#3F0','#6F3','#390','#6C0','#9F3','#CC9','#FF9','#C96','#C60','#C99','#F9C','#C69','#936','#603','#C09','#303',
'#0C0','#3C0','#360','#693','#9C6','#CF9','#FFC','#FC9','#F93','#FCC','#C9C','#969','#939','#909','#636','#606',
'#060','#3C3','#6C6','#0F0','#3F3','#6F6','#9F9','#CFC','#9CF','#FCF','#F9F','#F6F','#F3F','#F0F','#C6C','#C3C',
'#030','#363','#090','#393','#696','#9C9','#CFF','#39F','#69C','#CCF','#C9F','#96C','#639','#306','#90C','#C0C',
'#0F3','#0C3','#063','#396','#6C9','#9FC','#9CC','#06C','#369','#99F','#99C','#93F','#60C','#609','#C3F','#C0F',
'#0F6','#3F6','#093','#0C6','#3F9','#9FF','#699','#036','#039','#66F','#66C','#669','#309','#93C','#C6F','#90F',
'#0F9','#6F9','#3C6','#096','#6FF','#6CC','#366','#069','#36C','#33F','#33C','#339','#336','#63C','#96F','#60F',
'#0FC','#6FC','#3C9','#3FF','#3CC','#399','#033','#39C','#69F','#00F','#00C','#009','#006','#003','#63F','#30F',
'#0C9','#3FC','#0FF','#0CC','#099','#066','#3CF','#6CF','#09C','#36F','#0CF','#09F','#06F','#03F','#03C','#30C'
],
colorPicker : null,
pickColorHandler: null,
userData: null
};
wikibarColorTool.paletteName = wikibarColorTool.defaultPaletteName;
wikibarColorTool.columns = wikibarColorTool.defaultColumns;
wikibarColorTool.palette = wikibarColorTool.defaultPalette;
wikibarColorTool.onPickColor = function(e){
if (!e){ e = window.event; }
var theCell = resolveTarget(e);
if(!theCell){ return(false); }
color = theCell.bgColor.toLowerCase();
if(!color) { return; }
wikibarColorTool.displayColorPicker(false);
if(wikibarColorTool.pickColorHandler){
wikibarColorTool.pickColorHandler(color, wikibarColorTool.userData);
}
return(false);
};
wikibarColorTool.onMouseOver = function(e){
if (!e){ e = window.event; }
var theButton = resolveTarget(e);
if(!theButton){ return(false); }
if(!wikibarColorTool) { return; }
color = theButton.bgColor.toUpperCase();
if(!color) { return; }
td=document.getElementById('colorPickerInfo');
if(!td) { return; }
td.bgColor = color;
td.innerHTML = '<span style=\"color:#000;\">'+color+'</span> ' +
'<span style=\"color:#fff;\">'+color+'</span>';
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return(false);
};
wikibarColorTool.openColorPicker = function(theTarget, pickColorHandler, userData){
wikibarColorTool.skipClickDocumentEvent = true;
wikibarColorTool.pickColorHandler = pickColorHandler;
wikibarColorTool.userData = userData;
wikibarColorTool.moveColorPicker(theTarget);
};
wikibarColorTool.convert3to6HexColor = function(c){
c=c.trim();
var rx=/^\#(\d|[a-f])(\d|[a-f])(\d|[a-f])$/gi;
return (rx.test(c)? c.replace(rx, '#$1$1$2$2$3$3') : c);
};
wikibarColorTool.numToHexColor = function (n){
if(typeof(n)=='number' && (n>=0 && n<=255)) {
s = n.toString(16).toLowerCase();
return ((s.length==1)? '0'+s : s);
}else{
return null;
}
};
wikibarColorTool.renderColorPalette = function(){
if(wikibarColorTool.paletteName==wikibarColorTool.defaultPaletteName){
wikibarColorTool.palette=wikibarColorTool.defaultPalette;
wikibarColorTool.columns=wikibarColorTool.defaultColumns;
return;
}
tiddlerText = (store.getTiddlerText(wikibarColorTool.paletteName, '')).trim();
if(tiddlerText.length<=0) { return; }
var cpContents = tiddlerText.split('\n');
var colors=[];
columns = wikibarColorTool.defaultColumns;
var tmpArray=null;
errCount=0;
for(var i=0; i<cpContents.length; i++){
cpLine=cpContents[i].trim();
if( (!cpLine) || (cpLine.length<=0) || (cpLine.charAt(0) == '#') ){ continue; }
if(cpLine.substring(0,8).toLowerCase()=='columns:'){
tmpArray = cpLine.split(':');
try{
columns = parseInt(tmpArray[1],10);
}catch(ex){
columns = wikibarColorTool.defaultColumns;
}
}else{
tmpArray = cpLine.replace('\t', ' ').split(/[ ]{1,}/);
try{
color='';
for(var j=0; j<3; j++){
c=parseInt(tmpArray[j].trim(), 10);
if(isNaN(c)){
break;
}else{
c=wikibarColorTool.numToHexColor(c);
if(!c) {break;}
color+=c;
}
}
if(color.length==6){
colors.push('#'+color);
} else {
throw 'error';
}
}catch(ex){
}
}
}
if(colors.length>0){
wikibarColorTool.palette = colors;
wikibarColorTool.columns = columns;
}else{
throw 'renderColorPalette(): No color defined in the palette.';
}
};
wikibarColorTool.displayColorPicker = function(visible){
if(wikibarColorTool.colorPicker){
wikibarColorTool.colorPicker.style.display = (visible? 'block' : 'none');
}
};
wikibarColorTool.moveColorPicker = function(theTarget){
if(!wikibarColorTool.colorPicker){
wikibarColorTool.createColorPicker();
}
var cp = wikibarColorTool.colorPicker;
var rootLeft = findPosX(theTarget);
var rootTop = findPosY(theTarget);
var popupLeft = rootLeft;
var popupTop = rootTop;
var popupWidth = cp.offsetWidth;
var winWidth = findWindowWidth();
if(popupLeft + popupWidth > winWidth){
popupLeft = winWidth - popupWidth;
}
cp.style.left = popupLeft + 'px';
cp.style.top = popupTop + 'px';
wikibarColorTool.displayColorPicker(true);
};
wikibarColorTool.createColorPicker = function(unused, palette){
if(palette){ wikibarColorTool.paletteName=palette; }
wikibarColorTool.renderColorPalette();
wikibarColorTool.colorPicker = document.createElement('div');
wikibarColorTool.colorPicker.id = 'colorPicker';
document.body.appendChild(wikibarColorTool.colorPicker);
var theTable = document.createElement('table');
wikibarColorTool.colorPicker.appendChild(theTable);
var theTR = document.createElement('tr');
theTable.appendChild(theTR);
var theTD = document.createElement('td');
theTD.className = 'header';
theTD.colSpan = wikibarColorTool.columns;
theTD.innerHTML = wikibarColorTool.paletteName;
theTR.appendChild(theTD);
for(var i=0; i<wikibarColorTool.palette.length; i++){
if((i%wikibarColorTool.columns)===0){
theTR = document.createElement('tr');
theTable.appendChild(theTR);
}
theTD = document.createElement('td');
theTD.className = 'cell';
theTD.bgColor = wikibarColorTool.convert3to6HexColor(wikibarColorTool.palette[i]);
theTD.onclick = wikibarColorTool.onPickColor;
theTD.onmouseover = wikibarColorTool.onMouseOver;
theTR.appendChild(theTD);
}
rest = wikibarColorTool.palette.length % wikibarColorTool.columns;
if(rest>0){
theTD = document.createElement('td');
theTD.colSpan = wikibarColorTool.columns-rest;
theTD.bgColor = '#000000';
theTR.appendChild(theTD);
}
theTR = document.createElement('tr');
theTable.appendChild(theTR);
theTD = document.createElement('td');
theTD.colSpan = wikibarColorTool.columns;
theTD.id = 'colorPickerInfo';
theTR.appendChild(theTD);
};
wikibarColorTool.onDocumentClick = function(e){
if (!e){ e = window.event; }
if(wikibarColorTool.skipClickDocumentEvent) {
wikibarColorTool.skipClickDocumentEvent = false;
return true;
}
if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
wikibarColorTool.displayColorPicker(false);
}
return true;
};
function wikibar_doSelectPalette(param){
clearMessage();
var theButton = param.button;
if(!theButton.toolItem.key) { return; }
var palette = theButton.toolItem.key;
var oldPaletteName = wikibarColorTool.paletteName;
if(oldPaletteName != palette){
try{
wikibarColorTool.createColorPicker(theButton, palette);
displayMessage('Palette \"'+palette+'\" ('+ wikibarColorTool.palette.length +' colors) is selected');
}catch(ex){
errMsg = ex;
if(errMsg.substring(0,18)=='renderColorPalette'){
displayMessage('Invalid palette \"' + palette + '\", please check it out!');
wikibarColorTool.createColorPicker(theButton, oldPaletteName);
}
}
}
}
var wikibarPopup = {
skipClickDocumentEvent: false,
stack: []
};
wikibarPopup.resolveRootPopup = function(o){
if(o.isOnMainMenu){ return null; }
if(o.className.substring(0,12)=='wikibarPopup'){ return o;}
return wikibarPopup.resolveRootPopup(o.parentNode);
};
wikibarPopup.create = function(root){
for(var i=0; i<wikibarPopup.stack.length; i++){
var p=wikibarPopup.stack[i];
if(p.root==root){
wikibarPopup.removeFrom(i+1);
return null;
}
}
var rootPopup = wikibarPopup.resolveRootPopup(root);
if(!rootPopup){
wikibarPopup.remove();
}else{
wikibarPopup.removeFromRootPopup(rootPopup);
}
var popup = createTiddlyElement(document.body,'div','wikibarPopup'+root.toolItem.key,'wikibarPopup');
var pop = createTiddlyElement(popup,'table','','');
wikibarPopup.stack.push({rootPopup: rootPopup, root: root, popup: popup});
return pop;
};
wikibarPopup.show = function(unused,slowly){
var curr = wikibarPopup.stack[wikibarPopup.stack.length-1];
var overlayWidth = 1;
var rootLeft, rootTop, rootWidth, rootHeight, popupLeft, popupTop, popupWidth;
if(curr.rootPopup){
rootLeft = findPosX(curr.rootPopup);
rootTop = findPosY(curr.root);
rootWidth = curr.rootPopup.offsetWidth;
popupLeft = rootLeft + rootWidth - overlayWidth;
popupTop = rootTop;
}else{
rootLeft = findPosX(curr.root);
rootTop = findPosY(curr.root);
rootHeight = curr.root.offsetHeight;
popupLeft = rootLeft;
popupTop = rootTop + rootHeight;
}
var winWidth = findWindowWidth();
popupWidth = curr.popup.offsetWidth;
if(popupLeft + popupWidth > winWidth){
popupLeft = rootLeft - popupWidth + overlayWidth;
}
curr.popup.style.left = popupLeft + 'px';
curr.popup.style.top = popupTop + 'px';
curr.popup.style.display = 'block';
addClass(curr.root, 'highlight');
if(config.options.chkAnimate){
anim.startAnimating(new Scroller(curr.popup,slowly));
}else{
window.scrollTo(0,ensureVisible(curr.popup));
}
};
wikibarPopup.remove = function(){
if(wikibarPopup.stack.length > 0){
wikibarPopup.removeFrom(0);
}
};
wikibarPopup.removeFrom = function(from){
for(var t=wikibarPopup.stack.length-1; t>=from; t--){
var p = wikibarPopup.stack[t];
removeClass(p.root,'highlight');
p.popup.parentNode.removeChild(p.popup);
}
wikibarPopup.stack = wikibarPopup.stack.slice(0,from);
};
wikibarPopup.removeFromRootPopup = function(from){
for(var t=0; t<wikibarPopup.stack.length; t++){
var p = wikibarPopup.stack[t];
if(p.rootPopup==from){
wikibarPopup.removeFrom(t);
break;
}
}
};
wikibarPopup.onDocumentClick = function(e){
if (!e){ e = window.event; }
if(wikibarPopup.skipClickDocumentEvent){
wikibarPopup.skipClickDocumentEvent=false;
return true;
}
if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
wikibarPopup.remove();
}
return true;
};
var wikibarStore = {
TYPE: 'MAIN_MENU',
help:{
TYPE:'MENU',
CAPTION: '<font face=\"verdana\">?</font>',
TOOLTIP: 'about WikiBar',
options:{
TYPE:'MENU',
DYNAITEM: wikibar_genWikibarOptions
},
about:{
TYPE:'MENU',
DYNAITEM: wikibar_genWikibarAbout
}
},
preview:{
TOOLTIP: 'preview this tiddler',
CAPTION: '<font face=\"verdana\">∞</font>',
HANDLER: wikibar_doPreview
},
line:{
TOOLTIP: 'horizontal line',
CAPTION: '<font face=\"verdana\">—</font>',
syntax: '\n----\n',
HANDLER: wikibar_editFormatByCursor
},
crlf:{
TOOLTIP: 'new line',
CAPTION: '<font face=\"verdana\">¶</font>',
syntax: '\n',
HANDLER: wikibar_editFormatByCursor
},
selectAll:{
TOOLTIP: 'select all',
CAPTION: '<font face=\"verdana\">§</font>',
HANDLER: wikibar_editSelectAll
},
deleteSelected:{
TOOLTIP: 'delete selected',
CAPTION: '<font face=\"verdana\">×</font>',
syntax: '',
HANDLER: wikibar_editFormat
},
textFormat:{
TYPE: 'MENU',
CAPTION: 'text',
TOOLTIP: 'text formatters',
ignore:{
TOOLTIP: 'ignore wiki word',
CAPTION: 'ignore wikiWord',
syntax: '~user_text',
hint: 'wiki_word',
HANDLER: wikibar_editFormatByWord
},
bolder:{
TOOLTIP: 'bolder text',
CAPTION: '<strong>bolder</strong>',
syntax: "''user_text''",
hint: 'bold_text',
HANDLER: wikibar_editFormatByWord
},
italic:{
TOOLTIP: 'italic text',
CAPTION: '<em>italic</em>',
syntax: '\/\/user_text\/\/',
hint: 'italic_text',
HANDLER: wikibar_editFormatByWord
},
underline:{
TOOLTIP: 'underline text',
CAPTION: '<u>underline</u>',
syntax: '__user_text__',
hint: 'underline_text',
HANDLER: wikibar_editFormatByWord
},
strikethrough:{
TOOLTIP: 'strikethrough text',
CAPTION: '<strike>strikethrough</strike>',
syntax: '==user_text==',
hint: 'strikethrough_text',
HANDLER: wikibar_editFormatByWord
},
superscript:{
TOOLTIP: 'superscript text',
CAPTION: 'X<sup>superscript</sup>',
syntax: '^^user_text^^',
hint: 'superscript_text',
HANDLER: wikibar_editFormatByWord
},
subscript:{
TOOLTIP: 'subscript text',
CAPTION: 'X<sub>subscript</sub>',
syntax: '~~user_text~~',
hint: 'subscript_text',
HANDLER: wikibar_editFormatByWord
},
comment:{
TOOLTIP: 'comment text',
CAPTION: 'comment text',
syntax: '/%user_text%/',
hint: 'comment_text',
HANDLER: wikibar_editFormatByWord
},
monospaced:{
TOOLTIP: 'monospaced text',
CAPTION: '<code>monospaced</code>',
syntax: '{{{user_text}}}',
hint: 'monospaced_text',
HANDLER: wikibar_editFormatByWord
}
},
paragraph:{
TYPE: 'MENU',
TOOLTIP: 'paragarph formatters',
list:{
TYPE: 'MENU',
TOOLTIP: 'list tools',
bullet:{
TOOLTIP: 'bullet point',
syntax: '*user_text',
hint: 'bullet_text',
HANDLER: wikibar_editFormatByLine
},
numbered:{
TOOLTIP: 'numbered list',
syntax: '#user_text',
hint: 'numbered_text',
HANDLER: wikibar_editFormatByLine
}
},
heading:{
TYPE: 'MENU',
heading1:{
CAPTION:'<h1>Heading 1</h1>',
TOOLTIP: 'Heading 1',
syntax: '!user_text',
hint: 'heading_1',
HANDLER: wikibar_editFormatByLine
},
heading2:{
CAPTION:'<h2>Heading 2<h2>',
TOOLTIP: 'Heading 2',
syntax: '!!user_text',
hint: 'heading_2',
HANDLER: wikibar_editFormatByLine
},
heading3:{
CAPTION:'<h3>Heading 3</h3>',
TOOLTIP: 'Heading 3',
syntax: '!!!user_text',
hint: 'heading_3',
HANDLER: wikibar_editFormatByLine
},
heading4:{
CAPTION:'<h4>Heading 4</h4>',
TOOLTIP: 'Heading 4',
syntax: '!!!!user_text',
hint: 'heading_4',
HANDLER: wikibar_editFormatByLine
},
heading5:{
CAPTION:'<h5>Heading 5</h5>',
TOOLTIP: 'Heading 5',
syntax: '!!!!!user_text',
hint: 'heading_5',
HANDLER: wikibar_editFormatByLine
}
},
comment:{
TYPE: 'MENU',
commentByLine:{
CAPTION:'comment by line',
TOOLTIP: 'line comment',
syntax: '/%user_text%/',
hint: 'comment_text',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION:'comment by block',
TOOLTIP: 'block comment',
syntax: '/%\nuser_text\n%/',
hint: 'comment_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
monospaced:{
TYPE: 'MENU',
monosByLine:{
CAPTION: 'monospaced by line',
TOOLTIP: 'line monospaced',
syntax: '{{{\nuser_text\n}}}',
hint: 'monospaced_text',
HANDLER: wikibar_editFormatByLine
},
monosByBlock:{
CAPTION: 'monospaced by block',
TOOLTIP: 'block monospaced',
syntax: '{{{\nuser_text\n}}}',
hint: 'monospaced_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
quote:{
TYPE: 'MENU',
quoteByLine:{
CAPTION: 'quote by line',
TOOLTIP: 'line quote',
syntax: '>user_text',
hint: 'quote_text',
HANDLER: wikibar_editFormatByLine
},
quoteByBlcok:{
CAPTION: 'quote by block',
TOOLTIP: 'block quote',
syntax: '<<<\nuser_text\n<<<',
hint: 'quote_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
plugin:{
TYPE: 'MENU',
code:{
CAPTION: 'code area',
TOOLTIP: 'block monospaced for plugin',
syntax: '\n\/\/{{{\nuser_text\n\/\/}}}\n',
hint: 'monospaced_plugin_code',
byBlock: true,
HANDLER: wikibar_editFormatByLine
},
commentByLine:{
CAPTION: 'comment by line',
TOOLTIP: 'line comment',
syntax: '\/\/user_text',
hint: 'plugin_comment',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION: 'comment by block',
TOOLTIP: 'block comment',
syntax: '\/\***\nuser_text\n***\/',
hint: 'plugin_comment',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
css:{
TYPE: 'MENU',
code:{
CAPTION: 'code area',
TOOLTIP: 'block monospaced for css',
syntax: '\n\nuser_text\n\n',
hint: 'monospaced_css_code',
byBlock: true,
HANDLER: wikibar_editFormatByLine
},
commentByLine:{
CAPTION: 'comment by line',
TOOLTIP: 'line comment',
syntax: '',
hint: 'css_comment',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION: 'comment by block',
TOOLTIP: 'block comment',
syntax: '',
hint: 'css_comment',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
}
},
color:{
TYPE: 'MENU',
TOOLTIP: 'color tools',
highlight:{
CAPTION:'highlight text',
TOOLTIP: 'highlight text',
syntax: '@@user_text@@',
hint: 'highlight_text',
HANDLER: wikibar_editFormatByWord
},
color:{
CAPTION:'text color',
TOOLTIP: 'text color',
hint: 'your_text',
syntax: '@@color(%1):user_text@@',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByWord
},
bgcolor:{
CAPTION:'background color',
TOOLTIP: 'background color',
hint: 'your_text',
syntax: '@@bgcolor(%1):user_text@@',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByWord
},
colorcode:{
CAPTION:'color code',
TOOLTIP: 'insert color code',
syntax: '%1',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByCursor
},
'color palette':{
TYPE:'MENU',
DYNAITEM: wikibar_genPaletteSelector,
SEPERATOR:{},
morePalette:{
CAPTION:'more palettes',
TOOLTIP:'get more palettes',
HANDLER: wikibar_getMorePalette
}
}
},
link:{
TYPE: 'MENU',
TOOLTIP: 'insert link',
wiki:{
CAPTION:'wiki link',
TOOLTIP: 'wiki link',
syntax: '[[user_text]]',
hint: 'wiki_word',
HANDLER: wikibar_editFormatByWord
},
pretty:{
CAPTION: 'pretty link',
TOOLTIP: 'pretty link',
syntax: '[[user_text|%1]]',
hint: 'pretty_word',
param: 'PrettyLink Target',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
},
url:{
TOOLTIP: 'url link',
syntax: '[[user_text|%1]]',
hint: 'your_text',
param: 'http:\/\/...',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
},
image:{
TOOLTIP: 'image link',
syntax: '[img[user_text|%1]]',
hint: 'alt_text',
param: 'image/icon.jpg',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
}
},
macro:{},
more:{
TYPE: 'MENU',
TOOLTIP: 'more tools',
table:{
TYPE: 'MENU',
TOOLTIP: 'table',
table:{
CAPTION:'create table',
TOOLTIP: 'create a new table',
syntax: '\n%1\n',
HANDLER: wikibar_getTableRowCol,
doMore: wikibar_editFormatByWord
},
header:{
TOOLTIP: 'table header text',
syntax: '|user_text|c',
hint: 'table_header',
HANDLER: wikibar_editFormatByWord
},
cell:{
TOOLTIP: 'create a tabel cell',
syntax: '|user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByWord
},
columnHeader:{
CAPTION:'column header',
TOOLTIP: 'create a column header cell',
syntax: '|!user_text|',
hint: 'column_header',
HANDLER: wikibar_editFormatByWord
},
cell:{
TYPE: 'MENU',
CAPTION: 'cell options',
bgcolor:{
CAPTION: 'background color',
TOOLTIP: 'cell bgcolor',
syntax: '|bgcolor(%1):user_text|',
hint: 'your_text',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByTableCell
},
alignLeft:{
CAPTION: 'align left',
TOOLTIP: 'left align cell text',
syntax: '|user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
},
alignCenter:{
CAPTION: 'align center',
TOOLTIP: 'center align cell text',
syntax: '| user_text |',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
},
alignRight:{
CAPTION: 'align right',
TOOLTIP: 'right align cell text',
syntax: '| user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
}
}
},
html:{
TYPE: 'MENU',
html:{
CAPTION: '<html>',
TOOLTIP: 'html tag',
syntax: '<html>\nuser_text\n</html>',
hint: 'html_content',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
}
},
addon:{
TYPE: 'MENU',
TOOLTIP:'3rd party tools',
'about addons':{
TOOLTIP: 'list loaded addons',
HANDLER: wikibar_doListAddons
},
SEPERATOR:{}
}
};
addEvent(document, 'click', wikibarColorTool.onDocumentClick);
addEvent(document, 'click', wikibarPopup.onDocumentClick);
wikibar_install();
//}}}
/***
|Name|WikifyPlugin|
|Source|http://www.TiddlyTools.com/#WikifyPlugin|
|Documentation|http://www.TiddlyTools.com/#WikifyPluginInfo|
|Version|1.1.4|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|substitute fields, slices, or computed values into a wiki-syntax format string and render results dynamically|
The {{{<<wikify>>}}} macro allows you to easily retrieve values from custom tiddler fields, tiddler slices, computed values (using javascript) or just plain old literals, and assemble them into small bits of generated wiki-syntax text content that can be rendered directly into a tiddler, or used in the ViewTemplate or EditTemplate to add dynamically-generated content to each tiddler.
The {{{<<wikiCalc>>}}} macro performs the same processing as {{{<<wikify>>}}} and, in addition, passes the assembled text content through javascript's {{{eval()}}} function before rendering the results. This allows you to, for example, construct and compute mathematical expressions that use input values extracted from tiddler fields or slices.
!!!!!Documentation
> see [[WikifyPluginInfo]]
!!!!!Revisions
<<<
2009.03.29 [1.1.4] in handler(), pass 'tiddler' value to wikify() to fix macro errors in rendered content
|please see [[WikifyPluginInfo]] for additional revision details|
2007.06.22 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.WikifyPlugin= {major: 1, minor: 1, revision: 4, date: new Date(2009,3,29)};
config.macros.wikify={
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var fmt=params.shift();
var values=[];
var out="";
if (!fmt.match(/\%[0-9]/g) && params.length) // format has no markers, just join all params with spaces
out=fmt+" "+params.join(" ");
else { // format param has markers, get values and perform substitution
while (p=params.shift()) values.push(this.getFieldReference(place,p));
out=fmt.format(values);
}
if (macroName=="wikiCalc") out=eval(out).toString();
wikify(out.unescapeLineBreaks(),place,null,tiddler);
},
getFieldReference: function(place,p) { // "slicename::tiddlername" or "fieldname@tiddlername" or "fieldname"
if (typeof p != "string") return p; // literal non-string value... just return it...
var parts=p.split(config.textPrimitives.sliceSeparator);
if (parts.length==2) {// maybe a slice reference?
var tid=parts[0]; var slice=parts[1];
if (!tid || !tid.length || tid=="here") { // no target (or "here"), use containing tiddler
tid=story.findContainingTiddler(place);
if (tid) tid=tid.getAttribute("tiddler")
else tid="SiteSlices"; // fallback for 'non-tiddler' areas (e.g, header, sidebar, etc.)
}
var val=store.getTiddlerSlice(tid,slice); // get tiddler slice value
}
if (val==undefined) {// not a slice, or slice not found, maybe a field reference?
var parts=p.split("@");
var field=parts[0];
if (!field || !field.length) field="checked"; // missing fieldname, fallback: checked@tiddlername
var tid=parts[1];
if (!tid || !tid.length || tid=="here") { // no target (or "here"), use containing tiddler
tid=story.findContainingTiddler(place);
if (tid) tid=tid.getAttribute("tiddler")
else tid="SiteFields"; // fallback for 'non-tiddler' areas (e.g, header, sidebar, etc.)
}
var val=store.getValue(tid,field);
}
// not a slice or field, or slice/field not found... return value unchanged
return val===undefined?p:val;
}
}
//}}}
//{{{
// define alternative macroName for triggering pre-rendering call to eval()
config.macros.wikiCalc=config.macros.wikify;
//}}}
/***
|''Name''|eMailMacro|
|''Source''|[[FND's DevPad|http://devpad.tiddlyspot.com/#eMailMacro]]|
|''Version''|0.97|
|''Status''|stable|
|''Author''|Rick Magers, FND|
|''Contributors''|HeX|
|''License''|public domain|
|''~CoreVersion''|2.1|
|''Type''|macro|
|''Requires''|N/A|
|''Overrides''|N/A|
|''Description''|create an e-mail from tiddler contents|
!Usage
{{{
<<email
[tiddler:"name"]
[to:"address"]
[cc:"address"]
[bcc:"address"]
[subject:"text"]
[maxChars:"number"]
[filterMacro:"true"]
[label:"text"]
[tooltip:"text"]
[permalink:"true"]
[class:"customClass"]
>>
}}}
All parameters are optional.
Multiple recipients can be added by separating the addresses with a comma.
!!Example
<<email subject:"Hello World" to:"foo@bar.baz,bar@foo.baz" label:"mail to Foo" tooltip:"send this tiddler to Foo" permalink:"true">>
!!Adding the macro to the toolbar
After importing this plugin tiddler, the [[ViewTemplate]] needs to be modified by adding {{{<span macro='email'></span>}}} to the toolbar:
{{{
<div class='toolbar'>
<span macro='toolbar newHere +editTiddler deleteTiddler permalink references jump closeOthers -closeTiddler'>
<span macro='email'></span>
</div>
}}}
(The respective version of the ViewTemplate might differ from the one displayed here.)
!Limitations
* limited number of characters for the message body (due to [[inherent limitations|http://www.boutell.com/newfaq/misc/urllength.html]] of {{{mailto:}}} links)
* the user's combination of browser and e-mail client needs to support the respective features of the mailto protocol
!Revision History
!!v0.1 (2007-06-16)
* initial release [[by Rick Magers|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/ff7ae93cbe94345e/f6699532351f0802?#f6699532351f0802]]
!!v0.8 (2007-07-05)
* various modifications to enhance support for special characters ([[by FND and HeX|http://groups.google.com/group/TiddlyWikiDev/browse_thread/thread/ed196a32b295d2c9]])
!!v0.9 (2007-10-08)
* code refactoring
* added parameters for various fields
!!v0.91 (2007-10-10)
* fixed malformed mailto string (additional ampersand in some cases)
!!v0.95 (2007-12-27)
* added parameter for removing {{{<<email>>}}} macro calls from output (thanks [[ELS|http://www.tiddlytools.com]])
* using custom {{{escapeHTML()}}} function instead of {{{htmlDecode()}}}
!!v0.96 (2007-12-28)
* added parameter for specifying a target tiddler
* added parameter for limiting the number of characters returned from the tiddler body (default: 2000)
* some code refactoring
!!v0.97 (2009-03-19)
* added permalink parameter
!To Do
* documentation
* further enhance handling of special characters
!Code
***/
//{{{
(function() {
config.macros.email = {
subject: "default title",
body: "default contents",
label: "e-mail",
tooltip: "e-mail this tiddler",
btnClass: "button",
maxChars: 2000
};
config.macros.email.handler = function(place, macroName, params, wikifier, paramString, tiddler) {
// process parameters
var prms = paramString.parseParams(null, null, true);
var label = getParam(prms, "label") || this.label;
var tooltip = getParam(prms, "tooltip") || this.tooltip;
var btnClass = getParam(prms, "class") || this.btnClass;
var msgTo = getParam(prms, "to");
var msgCC = getParam(prms, "cc");
var msgBCC = getParam(prms, "bcc");
var msgSubject = getParam(prms, "subject");
var title = getParam(prms, "tiddler") || tiddler.title;
var filterMacro = getParam(prms, "filterMacro") == "true";
var permalink = getParam(prms, "permalink") == "true";
var maxChars = getParam(prms, "maxChars") || this.maxChars;
// retrieve tiddler contents
if(!msgSubject) {
if(store.getTiddler(title) || store.isShadowTiddler(title)) {
msgSubject = strEscape(title);
} else {
msgSubject = this.subject;
}
}
var msgBody = store.getTiddlerText(title, this.body);
if(permalink) {
config.commands.permalink.handler(null, null, tiddler.title); // XXX: hacky
msgBody = window.location.toString() + "\n\n" + msgBody;
}
if(filterMacro) {
msgBody = msgBody.replace(/<<email(.*|\n)?\>\>/gi, "");
}
msgBody = strEscape(msgBody);
// compose message
var msg = "";
if(msgTo) {
msg += msgTo;
}
msg += "?";
msg += "subject=" + msgSubject;
if(msgCC) {
msg += "&cc=" + msgCC;
}
if(msgBCC) {
msg += "&bcc=" + msgBCC;
}
msg += "&body=" + msgBody;
if(msg.length > maxChars) {
msg = msg.substr(0, maxChars);
}
// create link
wikify("[[" + label + "|" + "mailto:" + msg + "]]", place);
place.lastChild.className = btnClass;
place.lastChild.title = tooltip;
};
var strEscape = function(str) {
return entitify(escape(escapeHTML(str)));
};
/* inspired by the Prototype library (http://prototype.conio.net) */
var escapeHTML = function(str) {
var div = document.createElement("div");
var text = document.createTextNode(str);
div.appendChild(text);
return div.innerHTML;
};
// handle special characters
var entitify = function(str) {
return str
.replace(/%A2/g, "¢")
.replace(/%A3/g, "£")
.replace(/%A5/g, "Â¥")
.replace(/%AB/g, "«")
.replace(/%BB/g, "»")
.replace(/%B5/g, "µ")
.replace(/%C4/g, "Ä")
.replace(/%C5/g, "Ã…")
.replace(/%C6/g, "Æ")
.replace(/%D6/g, "Ö")
.replace(/%D8/g, "Ø")
.replace(/%DC/g, "Ü")
.replace(/%DF/g, "ß")
.replace(/%E4/g, "ä")
.replace(/%E5/g, "Ã¥")
.replace(/%E6/g, "æ")
.replace(/%F0/g, "ð")
.replace(/%F6/g, "ö")
.replace(/%F8/g, "ø")
.replace(/%FC/g, "ü")
.replace(/%u20AC/g, "€");
};
})();
//}}}
<<newHere title:"Ny herfra">>