//-- //-- TiddlyWiki-specific utility functions //-- // Returns TiddlyWiki version string function formatVersion(v) { v = v || version; return v.major + "." + v.minor + "." + v.revision + (v.alpha ? " (alpha " + v.alpha + ")" : "") + (v.beta ? " (beta " + v.beta + ")" : ""); } //# Compares two TiddlyWiki version objects //# Returns +1 if v2 is later than v1 //# 0 if v2 is the same as v1 //# -1 if v2 is earlier than v1 //# version without a beta number is later than a version with a beta number function compareVersions(v1,v2) { var x1,x2,i,a = ["major","minor","revision"]; for(i = 0; ix2) return -1; } x1 = v1.beta || 9999; x2 = v2.beta || 9999; if(x1 x2 ? -1 : 0; } function merge(dst,src,preserveExisting) { var i; for(i in src) { if(!preserveExisting || dst[i] === undefined) dst[i] = src[i]; } return dst; } // Resolve the target object of an event function resolveTarget(e) { var obj; if(e.target) obj = e.target; else if(e.srcElement) obj = e.srcElement; if(obj.nodeType == 3) // defeat Safari bug obj = obj.parentNode; return obj; } // Returns a string containing the description of an exception, optionally prepended by a message function exceptionText(e,message) { var s = e.description || e.toString(); return message ? "%0:\n%1".format([message,s]) : s; } // Displays an alert of an exception description with optional message function showException(e,message) { alert(exceptionText(e,message)); } function alertAndThrow(m) { alert(m); throw(m); } function glyph(name) { var g = config.glyphs; var b = g.currBrowser; if(b == null) { b = 0; while(b < g.browsers.length-1 && !g.browsers[b]()) b++; g.currBrowser = b; } if(!g.codes[name]) return ""; return g.codes[name][b]; } function createTiddlyText(parent,text) { return parent.appendChild(document.createTextNode(text)); } function createTiddlyCheckbox(parent,caption,checked,onChange) { var cb = document.createElement("input"); cb.setAttribute("type","checkbox"); cb.onclick = onChange; parent.appendChild(cb); cb.checked = checked; cb.className = "chkOptionInput"; if(caption) wikify(caption,parent); return cb; } function createTiddlyElement(parent,element,id,className,text,attribs) { var n,e = document.createElement(element); if(className != null) e.className = className; if(id != null) e.setAttribute("id",id); if(text != null) e.appendChild(document.createTextNode(text)); if(attribs) { for(n in attribs) { e.setAttribute(n,attribs[n]); } } if(parent != null) parent.appendChild(e); return e; } function createTiddlyButton(parent,text,tooltip,action,className,id,accessKey,attribs) { var i,btn = document.createElement("a"); btn.setAttribute("href","javascript:;"); if(action) { btn.onclick = action; } if(tooltip) btn.setAttribute("title",tooltip); if(text) btn.appendChild(document.createTextNode(text)); btn.className = className || "button"; if(id) btn.id = id; if(attribs) { for(i in attribs) { btn.setAttribute(i,attribs[i]); } } if(parent) parent.appendChild(btn); if(accessKey) btn.setAttribute("accessKey",accessKey); return btn; } //# Create a link to an external resource //# place - element where the link should be created //# url - link target //# label - link text (optional) function createExternalLink(place,url,label) { var link = document.createElement("a"); link.className = "externalLink"; link.href = url; var f = config.messages.externalLinkTooltip; link.title = f ? f.format([url]) : url; if(config.options.chkOpenInNewWindow) link.target = "_blank"; place.appendChild(link); if(label) createTiddlyText(link, label); return link; } function getTiddlyLinkInfo(title,currClasses) { var classes = currClasses ? currClasses.split(" ") : []; classes.pushUnique("tiddlyLink"); var tiddler = store.fetchTiddler(title); var subTitle; if(tiddler) { subTitle = tiddler.getSubtitle(); classes.pushUnique("tiddlyLinkExisting"); classes.remove("tiddlyLinkNonExisting"); classes.remove("shadow"); } else { var f; classes.remove("tiddlyLinkExisting"); classes.pushUnique("tiddlyLinkNonExisting"); if(store.isShadowTiddler(title)) { f = config.messages.shadowedTiddlerToolTip; classes.pushUnique("shadow"); } else { f = config.messages.undefinedTiddlerToolTip; classes.remove("shadow"); } subTitle = f ? f.format([title]) : ""; } if(typeof config.annotations[title]=="string") subTitle = config.annotations[title]; return {classes: classes.join(" "),subTitle: subTitle}; } // Event handler for clicking on a tiddly link function onClickTiddlerLink(ev) { var e = ev || window.event; var target = resolveTarget(e); var link = target; var title = null; var fields = null; var noToggle = null; do { title = link.getAttribute("tiddlyLink"); fields = link.getAttribute("tiddlyFields"); noToggle = link.getAttribute("noToggle"); link = link.parentNode; } while(title == null && link != null); if(!store.isShadowTiddler(title)) { var f = fields ? fields.decodeHashMap() : {}; fields = String.encodeHashMap(merge(f,config.defaultCustomFields,true)); } if(title) { var toggling = e.metaKey || e.ctrlKey; if(config.options.chkToggleLinks) toggling = !toggling; if(noToggle) toggling = false; if(store.getTiddler(title)) fields = null; story.displayTiddler(target,title,null,true,null,fields,toggling); } clearMessage(); return false; } //# Create a link to a particular tiddler //# place - element where the link should be created //# title - title of target tiddler //# includeText - flag for whether to include the title as the text of the link //# className - custom CSS class for the link //# linkedFromTiddler - tiddler from which to inherit extended fields //# noToggle - flag to force the link to open the target, even if chkToggleLinks is on function createTiddlyLink(place,title,includeText,className,isStatic,linkedFromTiddler,noToggle) { var title = jQuery.trim(title); var text = includeText ? title : null; var i = getTiddlyLinkInfo(title,className); var btn = isStatic ? createExternalLink(place,store.getTiddlerText("SiteUrl",null) + "#" + title) : createTiddlyButton(place,text,i.subTitle,onClickTiddlerLink,i.classes); if(isStatic) btn.className += ' ' + className; btn.setAttribute("refresh","link"); btn.setAttribute("tiddlyLink",title); if(noToggle) btn.setAttribute("noToggle","true"); if(linkedFromTiddler) { var fields = linkedFromTiddler.getInheritedFields(); if(fields) btn.setAttribute("tiddlyFields",fields); } return btn; } function refreshTiddlyLink(e,title) { var i = getTiddlyLinkInfo(title,e.className); e.className = i.classes; e.title = i.subTitle; } function createTiddlyDropDown(place,onchange,options,defaultValue) { var sel = createTiddlyElement(place,"select"); sel.onchange = onchange; var t; for(t=0; t