Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
/***
|''Name''|ImageMacroPlugin|
|''Version''|0.9.4|
|''Description''|Allows the rendering of svg images in a TiddlyWiki|
|''Author''|Osmosoft|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Notes''|Currently only works in modern browsers (not IE)|
|''Requires''|BinaryTiddlersPlugin|
!Usage
{{{<<image SVG>>}}} will render the text of the tiddler with title SVG as an SVG image (but not in ie where it will fail silently)
!!Parameters
width/height: specify width/height parameters
link: make the image link to a given location
tiddlyLink: link to a tiddler
!Notes
Binary tiddlers in TiddlyWeb when passed through the wikifier will be shown as images.
eg. {{{<<view text wikified>>}}} on a binary tiddler will show the image.
{{{<<view fieldname image>>}}}
will render the value of the tiddler field 'fieldname' as an image. This field can contain a tid
{{{<<image SiteIcon>>}}}
will create an image tag where the tiddler has content type beginning image and not ending +xml
will attempt to create svg object in other scenarios
{{{<<image /photos/x.jpg>>}}}
will create an image tag with src /photos/x.jpg as long as there is not a tiddler called /photos/x.jpg in
which case it will render that tiddler as an image. Note for the case of svg files it will attempt to render as an svg if possible via the image
tag. It doesn't embed the svg in the dom for security reasons as svg code can contain javascript.
!Code
***/
//{{{
(function($) {
var macro = config.macros.image = {
shim: "/bags/common/tiddlers/shim",
ieVersion: config.browser.isIE ? parseInt(config.browser.ieVersion[1], 10) : false,
svgns: "http://www.w3.org/2000/svg",
xlinkns: "http://www.w3.org/1999/xlink",
svgAvailable: document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
_fixPrefix: 1,
_external_cache: {},
_image_tag_cache: {},
_image_dimensions: {},
locale: {
badImage: "This image cannot be displayed."
},
handler: function(place, macroName, params, wikifier, paramString, tiddler){
var imageSource = params[0];
// collect named arguments
var args = macro.getArguments(paramString, params);
this.renderImage(place, imageSource, args);
},
init: function() {
var startupImages = store.getTaggedTiddlers("systemImage");
var place = $("<div />").attr("id", "systemImageArea").appendTo("body").hide()[0];
for(var i = 0; i < startupImages.length; i++) {
var image = startupImages[i];
macro.renderImage(place, image.title, { idPrefix: "" });
}
var data = new Image();
data.onload = function() {
// note ie 8 only supports data uris up to 32k so cannot be relied on
macro.supportsDataUris = this.width != 1 || this.height != 1 ? false : true;
macro.supportsDataUris = macro.ieVersion && macro.ieVersion < 9 ? false : macro.supportsDataUris;
};
data.onerror = data.onload;
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
},
refreshImage: function(src) {
var elements = macro._image_tag_cache[src] ? macro._image_tag_cache[src] : [];
if(macro._image_dimensions[src]) {
macro._image_dimensions[src] = false;
}
for(var i = 0; i < elements.length; i++) {
var el = $(elements[i]);
var newSrc = "%0?nocache=%1".format(src, Math.random());
el.attr("src", newSrc); // force reload
}
},
isBinaryImageType: function(contentType) {
return (contentType && contentType.indexOf("image") === 0 &&
contentType.indexOf("+xml") != contentType.length - 4) ? true : false;
},
isImageTiddler: function(tiddler) {
return macro.isSVGTiddler(tiddler) || macro.isBinaryImageTiddler(tiddler);
},
isSVGTiddler: function(tiddler) {
var type = tiddler ? tiddler.fields['server.content-type'] : false;
return type == "image/svg+xml";
},
isBinaryImageTiddler: function(tiddler) {
return macro.isBinaryImageType(tiddler.fields['server.content-type']);
},
renderImage: function(place, imageSource, options) {
var imageTiddler = store.getTiddler(imageSource);
var container;
var classes = ["image"];
if(options.link) {
classes = classes.concat(["imageLink", "externalLink"]);
container = $("<a />").attr("href", options.link).appendTo(place)[0];
} else if(options.tiddlyLink) {
classes.push("imageLink");
container = createTiddlyLink(place, options.tiddlyLink, false);
} else {
container = $("<span />").appendTo(place)[0];
}
$(container).addClass(classes.join(" "));
options = options ? options : {};
if(imageTiddler && macro.isBinaryImageTiddler(imageTiddler)) { // handle the case where we have an image url
return macro._renderBinaryImageTiddler(container, imageTiddler, options);
} else if(imageTiddler){ // handle the case where we have a tiddler
return macro._renderSVGTiddler(container, imageTiddler, options);
} else { // we have a string representing a url
return macro._renderBinaryImageUrl(container, imageSource, options);
}
},
_renderAlternateText: function(container, options) {
var img;
var src = options.src || "";
if(options.width && options.height) {
img = $("<img />").attr("src", src).addClass("svgImageText").attr("width", options.width).
attr("height", options.height).appendTo(container);
}
var alt = options.alt;
if(img && alt) {
img.attr("alt", alt).attr("title", alt);
} else if(alt) {
$(container).addClass("svgImageText").text(alt);
}
macro._image_tag_cache[src] = img;
},
_renderSVGTiddler: function(place, tiddler, options) {
if(!options) {
options = {};
}
merge(options, { tiddler: tiddler, fix: true});
if(macro.svgAvailable) {
this._importSVG(place, options); // display the svg
} else if(options.altImage) {
var image = options.altImage;
delete options.altImage;
this._renderBinaryImageUrl(place, image, options);
} else {
this._renderAlternateText(place, options); // instead of showing the image show the alternate text.
}
},
_renderBinaryImageTiddler: function(place, tiddler, options) {
var resourceURI;
var fields = tiddler.fields;
if(fields["server.type"] == "tiddlyweb") { // construct an accurate url for the resource
resourceURI = "%0/%1/tiddlers/%2".format(config.defaultCustomFields["server.host"],
fields["server.workspace"], encodeURI(fields["server.title"]));
} else { // guess the url for the resource
resourceURI = tiddler.title;
}
var ctype = fields["server.content-type"] || tiddler.type;
var text = tiddler.text;
if(macro.supportsDataUris && ctype && text.indexOf("<html") == -1) {
var uri = "data:%0;base64,%1".format(ctype, text);
options.src = resourceURI;
return macro._renderBinaryImageUrl(place, uri, options);
} else if(options.src) {
return macro._renderBinaryImageUrl(place, options.src, options);
} else {
return macro._renderBinaryImageUrl(place, resourceURI, options);
}
},
_renderImageTag: function(container, src, width, height, options) {
var img;
img = $("<img />").appendTo(container);
if(height) {
img.attr("height", height);
}
if(width) {
img.attr("width", width);
}
if(macro.ieVersion && macro.ieVersion < 7 && macro.shim && options.ie6png) {
$(img).css({width: userW, height: userH,
filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%0', sizingMethod='scale')".format(src)
}).attr("src", macro.shim);
} else {
img.attr("src", src);
}
if(!macro._image_tag_cache[options.srcUrl]) {
macro._image_tag_cache[options.srcUrl] = [];
}
img = $(img).addClass(options.imageClass)[0];
macro._image_tag_cache[options.srcUrl].push(img);
return img;
},
_getDimensions: function(realDimensions, reqDimensions, preserve) {
var w = realDimensions.width;
var h = realDimensions.height;
var reqh = reqDimensions.height;
var reqw = reqDimensions.width;
var finalw = w, finalh = h;
var ratiow = reqw / w, ratioh = reqh / h;
var scaledw = ratioh * w;
var scaledh = ratiow * h;
if(!reqw && reqh) {
finalw = scaledw;
finalh = reqh;
} else if(reqw && !reqh) {
finalw = reqw;
finalh = scaledh;
} else if(reqh && reqw) {
var preserveWidth = w > h ? true : false;
if(preserve) {
if(preserveWidth && scaledh < reqh) {
finalh = scaledh;
finalw = reqw;
} else {
finalh = reqh;
finalw = scaledw;
}
} else {
finalw = reqw;
finalh = reqh;
}
}
return { width: parseInt(finalw, 10), height: parseInt(finalh, 10) };
},
_renderBinaryImageUrl: function(container, src, options) {
var srcUrl = options.src ? options.src : src;
srcUrl = srcUrl.indexOf("/") === -1 ? "/%0".format(srcUrl) : srcUrl; // for IE.
var image_dimensions = macro._image_dimensions[srcUrl];
var image = new Image(); // due to weird scaling issues where you use just a width or just a height
var createImageTag = function(dimensions, error) {
if(error) {
var altImage = options.altImage;
if(altImage) {
delete options.altImage;
macro._renderBinaryImageUrl(container, altImage, options);
} else {
options.src = src;
macro._renderAlternateText(container, options);
}
} else {
var dim = macro._getDimensions(dimensions, {
width: options.width, height: options.height }, options.preserveAspectRatio);
options.srcUrl = srcUrl;
macro._renderImageTag(container, src, dim.width, dim.height, options);
}
};
if(!image_dimensions) {
image.onload = function() {
var dimensions = { width: image.width, height: image.height};
macro._image_dimensions[srcUrl] = dimensions;
createImageTag(dimensions);
};
image.onerror = function() {
createImageTag(null, true);
};
image.src = src;
} else {
createImageTag(image_dimensions);
}
},
_generateIdPrefix: function(){
return "twsvgfix_" + (this._fixPrefix++).toString() + "_";
},
_fixSVG: function(childNodes, idPrefix) {
var urlPattern = /url\(\#([^\)]*)\)*/ig;
var fixes = [
{ attr: "id", pattern: /^(.*)$/ig },
{ attr: "href", namespace: macro.xlinkns, pattern: /^#(.*)$/ig }
];
var url_fixes = ["filter", "fill", "mask", "stroke", "style"];
for(var i = 0; i < url_fixes.length; i++) {
fixes.push({ attr: url_fixes[i], pattern: urlPattern });
}
for(var t = 0; t < childNodes.length; t++) {
var node = childNodes[t];
for(var a = 0; a < fixes.length; a++) {
var fix = fixes[a];
var attr = fix.attr;
var ns = fix.namespace || "";
if(node.hasAttributeNS && node.hasAttributeNS(ns, attr)) {
var v = node.getAttributeNS(ns, attr);
fix.pattern.lastIndex = 0;
var match = fix.pattern.exec(v);
if(match) {
// Make sure replacement string doesn't contain any single dollar signs
var toReplace = match[1];
if(toReplace.indexOf(idPrefix) !== 0 && toReplace.indexOf("twglobal_") !== 0) {
var replacement = (idPrefix + toReplace).replace("$", "$$$$");
v = v.replace(match[1], replacement);
}
node.setAttributeNS(ns, attr,v);
}
}
}
var children = node.childNodes;
if(children.length > 0) {
this._fixSVG(children, idPrefix);
}
}
},
_importSVG: function(place, options){
options = options ? options : {};
var svgDoc, tiddlerText = options.tiddler.text;
if (window.DOMParser) {
svgDoc = new DOMParser().parseFromString(tiddlerText, "application/xml").documentElement;
var idPrefix = options.idPrefix || this._generateIdPrefix();
this._fixSVG([svgDoc], idPrefix);
var el = document.importNode(svgDoc, true);
var svgHolder = document.createElementNS(macro.svgns,"svg");
var width = options.width;
var height = options.height;
if(width || height) {
if(width && height) { // set view box of containing svg element based on the svg viewbox and width and height.
var viewBox = el.getAttribute("viewBox");
var topLeft = "0 0";
if(viewBox) {
topLeft = viewBox.replace(/([0-9]*) +([0-9]*) +([0-9]*) +([0-9]*) */gi,"$1 $2");
}
svgHolder.setAttributeNS(macro.svgns, "viewBox", "0 0 %0 %1".format(width, height));
} else {
if(!width) {
width = el.getAttribute("width");
}
if(!height) {
height = el.getAttribute("height");
}
}
svgHolder.setAttribute("width", width);
svgHolder.setAttribute("height", height);
el.setAttribute("width", "100%");
el.setAttribute("height", "100%");
svgHolder.setAttribute("class", "svgImage svgIcon %0".format(options.imageClass || ""));
svgHolder.appendChild(el);
place.appendChild(svgHolder);
}
else {
var existing = el.className ? el.className.baseVal : "";
el.setAttribute("class","svgImage %0".format(existing));
place.appendChild(el);
}
// if a tiddler attribute is set this is read as a link
$("[tiddler], [tiddlyLink]", place).attr("refresh", "link").click(function(ev) {
var tiddler = $(ev.target).attr("tiddlyLink");
if(tiddler) {
story.displayTiddler(ev.target, tiddler);
}
});
}
},
getArguments: function(paramString, params) {
var args = paramString.parseParams("name", null, true, false, true)[0];
var options = {};
for(var id in args) {
if(true) {
var p = args[id];
if(id == "def") {
options[id] = p;
} else {
options[id] = p[0];
}
}
}
var width = isNaN(params[1]) ? false : parseInt(params[1], 10);
var height = isNaN(params[2]) ? false : parseInt(params[2], 10);
options.width = macro.lookupArgument(options, "width", width);
options.height = macro.lookupArgument(options, "height", height);
options.preserveAspectRatio = args.preserveAspectRatio &&
args.preserveAspectRatio[0] == "yes" ? true : false;
options.tiddlyLink = macro.lookupArgument(options, "tiddlyLink", false);
options.link = macro.lookupArgument(options, "link", false);
return options;
},
lookupArgument: function(args, id, ifEmpty) {
return args[id] ? args[id] : ifEmpty;
}
};
// update views
var _oldwikifiedview = config.macros.view.views.wikified;
// update wikifier to check tiddler type before rendering
merge(config.macros.view.views, {
wikified: function(value, place, params, wikifier, paramString, tiddler) {
if(macro.isImageTiddler(tiddler) && params[0] == "text") {
var newplace = $("<div />").addClass("wikifiedImage").appendTo(place)[0];
macro.renderImage(newplace, tiddler.title, { alt: macro.locale.badImage });
} else {
_oldwikifiedview.apply(this, arguments);
}
},
image: function(value, place, params, wikifier, paramString, tiddler) {
// a field can point to another tiddler whereas text is the current tiddler.
var title = params[0] == "text" ? tiddler.title : value;
var args = macro.getArguments(paramString, params);
macro.renderImage(place, title, args);
}
});
config.shadowTiddlers.StyleSheetImageMacro = [".wikifiedImage svg, .wikifiedImage .image { width: 80%; }",
".svgImageText { background-color:[[ColorPalette::Error]]; color:#ddd; display: inline-block; }",
"span.svgImageText { display: inline-block; overflow: hidden; }"
].join("");
store.addNotification("StyleSheetImageMacro", refreshStyles);
})(jQuery);
//}}}
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130301|6770|10166|4685|4887|321.6|2840.56|
|20130302|6772|10169|116|200|327.2|2923.21|
|20130303|6779|10176|270|379|320.9|2866.33|
|20130304|6783|10183|410|680|328.8|2849.28|
|20130305|6798|10201|868|1152|332.6|3065.84|
|20130306|6805|10214|927|1100|320.7|3001.36|
|20130307|6817|10227|819|975|582.7|266.4|
|20130308|6820|10238|1100|1376|325|2970.13|
|20130309|6824|10244|251|544|316.3|3038.67|
|20130310|6828|10251|180|382|319|3161.15|
|20130311|6834|10256|344|441|5425.8|524.79|
|20130312|6838|10264|1058|1202|359.4|338.12|
|20130313|6840|10268|422|543|377|3402.79|
|20130314|6846|10277|677|778|317.8|5468.57|
|20130315|6852|10284|295|379|325.9|2911.51|
|20130316|6857|10290|234|395|322|316.98|
|20130317|6860|10294|99|184|347.6|361.73|
|20130318|6863|10298|119|202|631.3|3083.78|
|20130319|6870|10306|355|507|321.3|2926.3|
|20130320|6877|10327|716|835|5428.7|3058.46|
|20130321|6878|10331|99|164|559.5|3183.13|
|20130322|6888|10341|335|439|322.6|2989.93|
|20130323|6896|10348|161|260|351.2|2974.04|
|20130324|6902|10354|322|394|328|2894.42|
|20130325|6908|10361|237|371|341.3|3131.6|
|20130326|6914|10369|163|279|356.9|3070.22|
|20130327|6921|10378|876|1029|340|238.53|
|20130328|6935|10398|435|559|336.4|2956.8|
|20130329|6945|10413|673|805|325.6|7021.03|
|20130330|6948|10416|108|311|353.1|2848.48|
|20130331|6949|10419|445|525|322.8|2832.47|
/*{{{*/
Background: #f6e6de
Foreground: #201008
PrimaryPale: #e8bca7
PrimaryLight: #d68762
PrimaryMid: #b2582e
PrimaryDark: #28140a
SecondaryPale: #a7cae8
SecondaryLight: #62a0d6
SecondaryMid: #2e75b2
SecondaryDark: #0a1a28
TertiaryPale: #a7dde8
TertiaryLight: #62c2d6
TertiaryMid: #2e9cb2
TertiaryDark: #0a2328
Error: #f88
ColorPaletteParameters: HSL([19|9], [0.585999132366851],[0.1|0.7846414344385266])
/*}}}*/
Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20121101|6083|9237|324|419|310.7|2577.91|
|20121102|6088|9243|193|279|316.2|227.96|
|20121103|6098|9254|142|250|309.7|2564.16|
|20121104|6101|9260|154|227|313|7445.13|
|20121105|6106|9265|936|1235|480.5|2817.05|
|20121106|6114|9274|473|604|308.6|2551.81|
|20121107|6119|9280|411|703|313.6|207.73|
|20121108|6129|9295|282|418|312|2595.59|
|20121109|6136|9305|675|790|314.7|6724.4|
|20121110|6138|9307|89|184|317.5|212.74|
|20121111|6142|9311|165|260|1229.5|5473.94|
|20121112|6147|9318|1524|1657|311.9|2630.28|
|20121113|6154|9328|305|425|316.1|2664.34|
|20121114|6160|9335|223|305|312.5|2607.71|
|20121115|6165|9340|308|443|344.2|2734.58|
|20121116|6172|9350|190|2748|306|430.12|
|20121117|6176|9356|106|253|311.5|2750.48|
|20121118|6180|9360|128|322|316.4|2633.54|
|20121119|6183|9364|128|242|478.4|3296.74|
|20121120|6189|9372|1402|1560|307.8|17521.5|
|20121121|6198|9381|151|230|314.2|14275.1|
|20121122|6209|9394|353|495|310.7|7389.99|
|20121123|6213|9402|255|437|306.4|7646.3|
|20121124|6217|9408|1211|1803|314.2|6771.54|
|20121125|6222|9413|919|1807|330.9|2488.6|
|20121126|6227|9420|351|485|315.9|2639.09|
|20121127|6233|9442|623|729|327.1|2426.29|
|20121128|6247|9459|474|721|312.5|2587.84|
|20121129|6270|9483|472|686|318.4|270.85|
|20121130|6274|9488|825|929|318.4|2570.87|
This space provides some information on the number of users and spaces in TiddlySpace by integrating several facets:
* A series of shell scripts gathers data from the database on the server and then uses {{{curl}}} to PUT it to this space in SomeInfo. See SomeInfo2010 for historical data.
* The space includes @jquery-gchart to present a graph of the info via macro ChartTablePlugin
* Created and Modified are the number of tiddlers created or modified that day.
!Month by Month, past year
<<charttable SomeInfoWindow>>
!Month by Month
Since start of data
<<charttable SomeInfoMonthly>>
!2013
!!May
<<charttable>>
!!April
<<charttable SomeInfo201304>>
!!March
<<charttable SomeInfo201303>>
!!Feburary
<<charttable SomeInfo201302>>
!!January
<<charttable SomeInfo201301>>
!2012
!!December
<<charttable SomeInfo201212>>
!!November
<<charttable SomeInfo201211>>
!!October
<<charttable SomeInfo201210>>
!!September
<<charttable SomeInfo201209>>
!!August
<<charttable SomeInfo201208>>
!!July
<<charttable SomeInfo201207>>
!!June
<<charttable SomeInfo201206>>
!!May
<<charttable SomeInfo201205>>
!!April
<<charttable SomeInfo201204>>
!!March
<<charttable SomeInfo201203>>
@jquery-chart does not result in the slow script warnings that @charts does.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="14pt"
height="14pt"
viewBox="918 510 14 14"
id="svg3070">
<metadata
id="metadata3089">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3072">
<radialGradient
cx="0"
cy="0"
r="1"
id="Gradient"
gradientUnits="userSpaceOnUse">
<stop
id="stop3075"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop3077"
style="stop-color:#2b2b2b;stop-opacity:1"
offset="1" />
</radialGradient>
<radialGradient
id="Obj_Gradient"
xlink:href="#Gradient"
gradientTransform="matrix(11.473944,0,0,11.473944,922.3752,513.7837)" />
</defs>
<g
id="g3080"
style="fill:none;stroke:none">
<g
id="g3082">
<path
d="m 929.6952,512.9018 c -2.5384,-2.53843 -6.654,-2.53843 -9.1924,0 -2.5384,2.5384 -2.5384,6.654 0,9.19238 2.5384,2.53839 6.654,2.53839 9.1924,0 2.5384,-2.53838 2.5384,-6.65398 0,-9.19238 m -4.5962,2.8407 2.07733,-2.07734 1.75547,1.75549 -2.0773,2.07735 2.0773,2.07732 -1.75547,1.75548 -2.07733,-2.07732 -2.07733,2.07732 -1.75547,-1.75548 2.0773,-2.07732 -2.0773,-2.07735 1.75547,-1.75549 z"
id="path3084"
style="fill:url(#Obj_Gradient)" />
<path
d="m 927.61447,515.38354 a 4.51205,4.2590378 0 1 1 -9.0241,0 4.51205,4.2590378 0 1 1 9.0241,0 z"
transform="matrix(1.0218069,0,0,1.0462046,-18.063694,-21.648443)"
id="path2394"
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
</g>
</svg>
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
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 40 40"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs><linearGradient id="lG3826" x1="7.0996" gradientUnits="userSpaceOnUse" y1="18.829" gradientTransform="matrix(1.5858347,0,0,1.8078238,1098.1851,351.13716)" x2="1.5461" y2="-0.95166"><stop stop-color="#000" offset="0"/><stop stop-color="#9c9b99" offset="1"/></linearGradient><linearGradient id="lG3828" y2="372.44" gradientUnits="userSpaceOnUse" y1="375.7" x2="1111.7" x1="1097.7"><stop style="stop-color:#ac9393;" offset="0"/><stop style="stop-color:#c8b7b7;" offset="1"/></linearGradient></defs><g transform="translate(-1080.9375,-357.3329)"><path style="stroke-width:0;stroke-miterlimit:4;fill:url(#lG3826);" d="m1080.9,357.32,39.996-0.0426-0.01,40.008c-15.507-25.519-15.36-25.95-39.988-39.965z"/><path style="stroke-dashoffset:0;stroke:#7aa3be;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.49999988;fill:#c1e6fd;" d="m1091.9,363.55c6.5716-6.4925,16.576-7.3925,23.147-0.90003,6.5717,6.4925,6.5717,17.019,0,23.511-4.4424-8.6113-12.288-15.713-23.147-22.611z"/><path style="stroke-dashoffset:0;stroke:#ce81b0;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.5;fill:#f4c4e2;" d="m1110.2,367.62c3.217,3.2168,3.217,8.4323,0,11.649-3.8194-4.2357-8.3307-8.1824-11.649-11.649,3.217-3.2168,8.4325-3.2168,11.649-0.00002z"/><path style="stroke-linejoin:bevel;stroke:#000000;stroke-linecap:round;stroke-dasharray:none;stroke-miterlimit:4;stroke-width:0.80000001;fill:url(#lG3828);" d="m1081,357.34c18.79,6.4752,32.53,16.56,39.894,39.892-11.19-17.028-14.878-19.19-27.352-14.96,6.2984-12.098,3.9371-13.19-12.542-24.932z"/></g></svg>
|Date|Users|Spaces|
|20110201|960|2247|
|20110202|962|2251|
|20110203|963|2255|
|20110204|964|2256|
|20110205|965|2259|
|20110206|965|2260|
|20110207|966|2263|
|20110208|967|2267|
|20110209|968|2270|
|20110210|977|2284|
|20110211|982|2293|
|20110212|986|2301|
|20110213|991|2309|
|20110214|994|2319|
|20110215|996|2322|
|20110216|1002|2331|
|20110217|1007|2343|
|20110218|1013|2348|
|20110219|1018|2357|
|20110220|1024|2364|
|20110221|1030|2373|
|20110222|1035|2383|
|20110223|1039|2389|
|20110224|1042|2394|
|20110225|1047|2402|
|20110226|1048|2404|
|20110227|1050|2407|
|20110228|1051|2409|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>jQuery Google Chart</title>
<style type="text/css">
#basicGChart { width: 450px; height: 300px }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="/jquery.gchart"></script>
<script type="text/javascript">
$(function () {
$('#basicGChart').gchart({type: 'line', maxValue: 40,
title: 'Weather for|Brisbane, Australia', titleColor: 'green',
backgroundColor: $.gchart.gradient('horizontal', 'ccffff', 'ccffff00'),
series: [$.gchart.series('Max', [29.1, 28.9, 28.1, 26.3,
23.5, 21.2, 20.6, 21.7, 23.8, 25.6, 27.3, 28.6], 'red', 'ffcccc'),
$.gchart.series('Min', [20.9, 20.8, 19.5, 16.9,
13.8, 10.9, 9.5, 10.0, 12.5, 15.6, 18.0, 19.8], 'green'),
$.gchart.series('Rainfall', [157.7, 174.6, 138.5, 90.4,
98.8, 71.2, 62.6, 42.7, 34.9, 94.4, 96.5, 126.2], 'blue', 0, 200)],
axes: [$.gchart.axis('bottom', ['Jan', 'Feb', 'Mar', 'Apr',
'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 'black'),
$.gchart.axis('left', 0, 40, 'red', 'right'),
$.gchart.axis('left', ['C'], [50], 'red', 'right'),
$.gchart.axis('right', 0, 200, 50, 'blue', 'left'),
$.gchart.axis('right', ['mm'], [50], 'blue', 'left')],
legend: 'right'});
});
</script>
</head>
<body>
<h1>jQuery Google Chart Basics</h1>
<p>This page demonstrates the very basics of the
<a href="http://keith-wood.name/gChart.html">jQuery Google Chart plugin</a>.
It contains the minimum requirements for using the plugin and
can be used as the basis for your own experimentation.</p>
<p>For more detail see the <a href="http://keith-wood.name/gChartRef.html">documentation reference</a> page.</p>
<div id="basicGChart"></div>
</body>
</html>
|Date|Users|Spaces|
|20110901|2849|5038|
|20110902|2855|5046|
|20110903|2871|5066|
|20110904|2878|5075|
|20110905|2886|5084|
|20110906|2895|5093|
|20110907|2912|5111|
|20110908|2919|5119|
|20110909|2937|5140|
|20110910|2959|5165|
|20110911|2968|5174|
|20110912|2983|5193|
|20110913|2990|5202|
|20110914|3003|5219|
|20110915|3015|5236|
|20110916|3020|5243|
|20110917|3028|5253|
|20110918|3035|5261|
|20110919|3044|5275|
|20110920|3054|5290|
|20110921|3063|5303|
|20110922|3079|5326|
|20110923|3095|5345|
|20110924|3169|5419|
|20110925|3186|5436|
|20110926|3197|5450|
|20110927|3212|5465|
|20110928|3235|5489|
|20110929|3245|5500|
|20110930|3255|5513|
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
|Date|Users|Spaces|
|20110301|1060|2422|
|20110302|1064|2428|
|20110303|1072|2444|
|20110304|1076|2449|
|20110305|1085|2460|
|20110306|1088|2468|
|20110307|1091|2471|
|20110308|1101|2488|
|20110309|1110|2503|
|20110310|1114|2509|
|20110311|1126|2529|
|20110312|1133|2539|
|20110313|1138|2546|
|20110314|1138|2549|
|20110315|1149|2563|
|20110316|1161|2581|
|20110317|1171|2594|
|20110318|1180|2611|
|20110319|1183|2617|
|20110320|1188|2625|
|20110321|1193|2635|
|20110322|1201|2644|
|20110323|1211|2663|
|20110324|1212|2675|
|20110325|1217|2686|
|20110326|1226|2700|
|20110327|1232|2708|
|20110328|1237|2715|
|20110329|1247|2732|
|20110330|1260|2754|
|20110331|1279|2776|
/***
|''Name''|TiddlySpaceSearcher|
|''Version''|0.2.5|
|''Requires''|TiddlySpaceConfig TiddlySpaceFollowingPlugin|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var tsScan = config.macros.tsScan;
config.shadowTiddlers.SearchTemplate = "<<view server.bag SiteIcon label:no width:24 height:24 preserveAspectRatio:yes>> <<view server.bag spaceLink title external:no>> in space <<view server.bag spaceLink>>";
config.shadowTiddlers.StyleSheetSearch = [".resultsArea .siteIcon { display: inline; }",
".searchForm {text-align: left;}"].join("\n");
store.addNotification("StyleSheetSearch", refreshStyles);
var search = config.macros.tsSearch = {
locale: {
advanced: "Advanced Options",
header: "Search",
resultsHeader: "Results (%0)",
find: "find",
noResults: "No tiddlers matched your search query",
query: "QUERY: ",
error: "please provide a search query or a tag, modifier or title!",
titleAdvanced: "where the title is",
modifierAdvanced: "where the last modifier is",
spaceAdvanced: "only in the space: ",
notspaceAdvanced: "but not in the spaces: ",
tagsAdvanced: "with the tags: "
},
andConstructor: function(container, label, fieldname, negationMode) {
var tags = $("<div />").appendTo(container);
$('<span />').text(label).appendTo(tags);
var id = "area" + Math.random();
container = $("<span />").attr("id", id).appendTo(tags)[0];
function add(container) {
var el = $('<input type="text" />').attr("field", fieldname).appendTo(container);
if(negationMode) {
el.attr("negation", "true");
}
}
add(container);
var el = $("<button />").text("AND").click(function(ev) {
add($(ev.target).data("container"));
ev.preventDefault();
}).appendTo(tags);
$(el).data("container", container);
},
fieldConstructor: function(container, label, field) {
container = $("<div />").appendTo(container)[0];
$("<span />").text(label).appendTo(container);
$("<input />").attr("text", "input").attr("field", field).appendTo(container);
},
advancedOptions: function(form) {
var locale = search.locale;
var container = $("<div />").addClass("tsAdvancedOptions").appendTo(form)[0];
$("<h2/ >").text(search.locale.advanced).appendTo(container);
$("<div />").addClass("separator").appendTo(container);
search.fieldConstructor(container, locale.titleAdvanced, "title");
search.fieldConstructor(container, locale.modifierAdvanced, "modifier");
search.fieldConstructor(container, locale.spaceAdvanced, "space");
search.andConstructor(container, locale.notspaceAdvanced, "space", true);
search.andConstructor(container, locale.tagsAdvanced, "tag");
},
constructSearchQuery: function(form) {
var data = [], select = [];
var query = $("[name=q]", form).val();
if(query) {
data.push("q=%0".format(query));
}
// add tags, fields etc..
$("[field]", form).each(function(i, el) {
var val = $(el).val();
var name = $(el).attr("field");
var negate = $(el).attr("negation") == "true";
if(val && name) {
val = encodeURIComponent(val);
val = negate ? "!" + val : val;
if(name == "space") {
val += "_public";
name = "bag";
}
if(negate) {
select.push("select=%0:%1".format(name,val));
} else {
var prefix = data.length === 0 ? "q=" : "";
data.push('%0%1:"%2"'.format(prefix, name, val));
}
}
});
var dataString = data.join(" ");
if(dataString.length === 0 && !query) {
return false;
}
var selectStatement = select.join("&");
if(dataString.length > 0 && selectStatement.length > 0) {
dataString += "&";
}
dataString += selectStatement;
return "/search?%0".format(dataString);
},
constructForm: function(place) {
var locale = search.locale;
$("<h1 />").text(locale.header).appendTo(place);
var form = $("<form />").appendTo(place)[0];
$('<input type="text" name="q" />').appendTo(form);
$('<input type="submit" />').val(locale.find).appendTo(form);
search.advancedOptions(form);
var query = $('<h2 class="query"/>').appendTo(place)[0];
var results = $("<div />").appendTo(place).addClass("resultsArea")[0];
var lookup = function(url) {
if(!url) {
results.empty().addClass("error").text(locale.error);
return;
}
config.extensions.tiddlyweb.getStatus(function(status) {
$(query).text(locale.query);
var href = status.server_host.url + url;
$("<a />").attr("href", href).text(href).appendTo(query);
tsScan.scan(results, { url: url, emptyMessage: search.locale.noResults, cache: true,
template: "SearchTemplate", sort: "title", callback: function(tiddlers) {
$("<h2 />").text(locale.resultsHeader.format(tiddlers.length)).prependTo(results);
}
});
});
};
$(form).submit(function(ev) {
ev.preventDefault();
var url = search.constructSearchQuery(form);
config.macros.tsSearch.lastSearch = url;
lookup(url);
});
if(search.lastSearch) {
lookup(search.lastSearch);
}
return form;
},
handler: function(place) {
var container = $("<div />").addClass("searchForm").appendTo(place)[0];
search.constructForm(container);
}
};
})(jQuery);
//}}}
|Date|Users|Spaces|
|20101112|627|1501|
|20101113|629|1506|
|20101114|642|1521|
|20101115|646|1531|
|20101116|652|1542|
|20101117|658|1562|
|20101118|661|1573|
|20101119|662|1578|
|20101120|667|1588|
|20101121|670|1600|
|20101122|672|1608|
|20101123|681|1623|
|20101124|682|1625|
|20101125|689|1641|
|20101126|692|1664|
|20101127|694|1671|
|20101128|697|1675|
|20101129|702|1687|
|20101130|702|1692|
|20101201|705|1697|
|20101202|708|1707|
|20101203|709|1737|
|20101204|715|1749|
|20101205|717|1752|
|20101206|721|1763|
|20101207|730|1776|
|20101208|736|1787|
|20101209|742|1797|
|20101210|745|1815|
|20101211|750|1829|
|20101212|752|1832|
|20101213|757|1845|
|20101214|764|1855|
|20101215|766|1861|
|20101216|769|1866|
|20101217|771|1873|
|20101218|777|1888|
|20101219|778|1891|
|20101220|783|1901|
|20101221|787|1908|
|20101222|797|1920|
|20101223|802|1931|
|20101224|804|1934|
|20101225|808|1941|
|20101226|811|1945|
|20101227|817|1952|
|20101228|823|1964|
|20101229|826|1974|
|20101230|832|1988|
|20101231|835|1992|
/***
|''Name''|TiddlyFileImporter|
|''Version''|0.3.8|
|''Author''|Ben Gillies|
|''Type''|plugin|
|''Description''|Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.|
!Usage
Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.
!Requires
tiddlyweb
tiddlywebplugins.reflector
!Code
***/
//{{{
(function($){
if(!version.extensions.TiddlyFileImporter)
{ //# ensure that the plugin is only installed once
version.extensions.TiddlyFileImporter = { installed: true };
}
config.macros.fileImport = {
reflectorURI: '/reflector?csrf_token=%0',
incorrectTypeError: 'Incorrect File Type. You must upload a TiddlyWiki',
uploadLabel: 'Upload',
uploadLabelPrompt: 'Import tiddlers from this TiddlyWiki',
step1FileText: 'File:',
step1PostText: 'In the next screen you will select the tiddlers to import.',
step1Title: 'Step 1: Pick a TiddlyWiki to import',
step1TypeChooser: 'Import From:',
step3Html: ['<input type="hidden" name="markList" />',
'<input type="hidden" checked="true" name="chkSync" />',
'<input type="hidden" name="chkSave" />',
'<input type="hidden" name="txtSaveTiddler" />'].join(),
handler: function(place, macroName, params, wikifier, paramString) {
var wizard = new Wizard();
wizard.createWizard(place, 'Import a TiddlyWiki');
this.restart(wizard);
},
restart: function(wizard) {
var me = config.macros.fileImport;
wizard.addStep(me.step1Title, ['<input type="hidden" ',
'name="markList" />'].join(""));
var markList = wizard.getElement('markList');
var uploadWrapper = document.createElement('div');
markList.parentNode.insertBefore(uploadWrapper, markList);
uploadWrapper.setAttribute('refresh', 'macro');
uploadWrapper.getAttribute('macroName', 'fileImport');
var iframeName = 'reflectorImporter' + Math.random().toString();
me.createForm(uploadWrapper, wizard, iframeName);
$(uploadWrapper).append('<p>' + me.step1PostText + '</p>');
wizard.setValue('serverType', 'tiddlyweb');
wizard.setValue('adaptor', new config.adaptors.file());
wizard.setValue('host', config.defaultCustomFields['server.host']);
wizard.setValue('context', {});
var iframe = $(['<iframe name="' + iframeName + '" ',
'style="display: none" />'].join("")).appendTo(uploadWrapper);
var onSubmit = function(ev) {
var uploadType = $('select[name=uploadtype]', wizard.formElem).val();
if (uploadType == "file") {
// set an onload ready to hijack the form
me.setOnLoad(uploadWrapper, wizard, iframe[0]);
wizard.importType = 'file';
wizard.formElem.submit();
} else {
var csrf_token = config.extensions.tiddlyspace.getCSRFToken();
$.ajax({
url: "%0/reflector?csrf_token=%1".format(
config.defaultCustomFields["server.host"], csrf_token),
type: "POST",
dataType: "text",
data: {
uri: $("input", ".importFrom", wizard.formElem).val()
},
success: function(data, txtStatus, xhr) {
wizard.POSTResponse = data;
me.importTiddlers(uploadWrapper, wizard);
},
error: function(xhr, txtStatus, error) {
displayMessage(["There was an error fetching the ",
'url: ', txtStatus].join(""));
me.restart(wizard);
}
});
return false;
}
};
wizard.setButtons([{
caption: me.uploadLabel,
tooltip: me.uploadLabelPrompt,
onClick: onSubmit
}]);
$(wizard.formElem).submit(function(ev) {
onSubmit(ev);
ev.preventDefault();
});
},
createForm: function(place, wizard, iframeName) {
var form = wizard.formElem;
var me = config.macros.fileImport;
form.action = me.reflectorURI.format(
config.extensions.tiddlyspace.getCSRFToken());
form.enctype = 'multipart/form-data';
form.encoding = 'multipart/form-data';
form.method = 'POST';
form.target = iframeName;
onSelectChange = function(e) {
var changeTo = $(this).val();
if (changeTo == "file") {
$(".importFrom").html('%0 <input type="file" name="file" />'.
format(me.step1FileText));
} else {
$(".importFrom").html('URL: <input type="text" name="uri" />'
+ ' Do you want <a target="_blank" href="http://faq.tiddlyspace.com/How%20do%20I%20include%2Fexclude%20spaces%3F">inclusion</a> instead?');
}
};
$(place).append('<span>%0</span>'.format(me.step1TypeChooser)).
append($(['<select name="uploadtype"><option value="file" selected="selected">file',
'<option value="uri">url</select>'].join("")).change(onSelectChange)).
append('<div class="importFrom">%0<input type="file" name="file" /></div>'.
format(me.step1FileText));
},
setOnLoad: function(place, wizard, iframe) {
var me = config.macros.fileImport;
var loadHandler = function() {
me.importTiddlers.apply(this, [place, wizard, iframe]);
};
iframe.onload = loadHandler;
completeReadyStateChanges = 0;
iframe.onreadystatechange = function() {
if (++(completeReadyStateChanges) == 5) {
loadHandler();
}
};
},
importTiddlers: function(place, wizard, iframe) {
var tmpStore = new TiddlyWiki();
var POSTedWiki = "";
if (wizard.importType == "file") {
try {
POSTedWiki= iframe.contentWindow
.document.documentElement.innerHTML;
} catch(e) {
displayMessage(config.macros.fileImport.incorrectTypeError);
config.macros.fileImport.restart(wizard);
return;
}
// now we are done, so remove the iframe
$(iframe).remove();
} else {
POSTedWiki = wizard.POSTResponse;
}
tmpStore.importTiddlyWiki(POSTedWiki);
var newTiddlers = tmpStore.getTiddlers();
var workspace = config.defaultCustomFields['server.workspace'];
var context = {
status: true,
statusText: 'OK',
httpStatus: 200,
adaptor: wizard.getValue('adaptor'),
tiddlers: newTiddlers
};
context.adaptor.store = tmpStore;
wizard.setValue('context', context);
wizard.setValue('workspace', workspace);
wizard.setValue('inFileImport', true);
config.macros.importTiddlers.onGetTiddlerList(context, wizard);
}
};
var _onGetTiddler = config.macros.importTiddlers.onGetTiddler;
config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
if (wizard.getValue('inFileImport')) {
var me = config.macros.importTiddlers;
if(!context.status)
displayMessage("Error in importTiddlers.onGetTiddler: " + context.statusText);
var tiddler = context.tiddler;
var fields = tiddler.fields;
merge(fields, config.defaultCustomFields);
fields["server.workspace"] = wizard.getValue('workspace');
delete fields['server.permissions'];
delete fields['server.bag'];
fields['server.page.revision'] = 'false';
delete fields['server.recipe'];
fields.changecount = 1;
store.suspendNotifications();
store.saveTiddler(tiddler.title, tiddler.title, tiddler.text,
tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields,
false, tiddler.created);
store.resumeNotifications();
var remainingImports = wizard.getValue("remainingImports")-1;
wizard.setValue("remainingImports",remainingImports);
if(remainingImports === 0) {
if(context.isSynchronous) {
store.notifyAll();
refreshDisplay();
}
wizard.setButtons([
{caption: me.doneLabel, tooltip: me.donePrompt, onClick: me.onClose}
],me.statusDoneImport);
autoSaveChanges();
}
} else {
_onGetTiddler.apply(this, arguments);
}
};
var _onCancel = config.macros.importTiddlers.onCancel;
config.macros.importTiddlers.onCancel = function(e)
{
var wizard = new Wizard(this);
if (!wizard.getValue('inFileImport')) {
return _onCancel.apply(this, arguments);
}
var place = wizard.clear();
config.macros.fileImport.restart(wizard);
return false;
};
var _step3Html = config.macros.importTiddlers.step3Html;
var _onGetTiddlerList = config.macros.importTiddlers.onGetTiddlerList;
config.macros.importTiddlers.onGetTiddlerList = function(context, wizard) {
var fileImport = config.macros.fileImport;
var importTiddlers = config.macros.importTiddlers;
if (wizard.getValue('inFileImport')) {
importTiddlers.step3Html = fileImport.step3Html;
} else {
importTiddlers.step3Html = _step3Html;
}
_onGetTiddlerList.apply(this, arguments);
};
})(jQuery);
//}}}
|Date|Users|Spaces|
|20110101|837|1998|
|20110102|837|2001|
|20110103|844|2013|
|20110104|852|2024|
|20110105|862|2040|
|20110106|866|2049|
|20110107|867|2055|
|20110108|874|2067|
|20110109|878|2074|
|20110110|880|2079|
|20110111|884|2083|
|20110112|889|2092|
|20110113|894|2097|
|20110114|895|2105|
|20110115|898|2122|
|20110116|901|2132|
|20110117|906|2139|
|20110118|907|2146|
|20110119|917|2162|
|20110120|920|2167|
|20110121|922|2172|
|20110122|924|2178|
|20110123|927|2184|
|20110125|932|2197|
|20110126|936|2207|
|20110127|940|2215|
|20110128|943|2221|
|20110129|946|2229|
|20110130|948|2231|
|20110131|957|2241|
|Date|Users|Spaces|
|20110601|1784|3525|
|20110602|1801|3546|
|20110603|1824|3585|
|20110604|1842|3612|
|20110605|1843|3613|
|20110606|1851|3625|
|20110607|1865|3641|
|20110608|1879|3666|
|20110609|1886|3680|
|20110610|1898|3698|
|20110611|1922|3728|
|20110612|1928|3735|
|20110613|1937|3744|
|20110614|1955|3778|
|20110615|1965|3796|
|20110616|1977|3814|
|20110617|1987|3830|
|20110618|1996|3846|
|20110619|2007|3864|
|20110620|2015|3875|
|20110621|2025|3901|
|20110622|2037|3916|
|20110623|2045|3927|
|20110624|2055|3938|
|20110625|2065|3963|
|20110626|2070|3973|
|20110627|2075|3982|
|20110628|2085|4002|
|20110629|2092|4030|
|20110630|2104|4046|
/***
https://github.com/tiddlyweb/chrjs/raw/master/main.js
***/
//{{{
// TiddlyWeb adaptor
// v0.14.3
/*jslint vars: true, unparam: true, nomen: true, white: true */
/*global jQuery */
var tiddlyweb = (function($) {
"use strict";
var tw = {
routes: {
// host is the TiddlyWeb instance's URI (including server_prefix)
// placeholders "_type" & "name" refer to the respective bag/recipe
root : "{host}/",
bags : "{host}/bags",
bag : "{host}/bags/{name}",
recipes : "{host}/recipes",
recipe : "{host}/recipes/{name}",
tiddlers : "{host}/{_type}s/{name}/tiddlers",
tiddler : "{host}/{_type}s/{name}/tiddlers/{title}",
revisions: "{host}/{_type}s/{name}/tiddlers/{title}/revisions",
revision : "{host}/{_type}s/{name}/tiddlers/{title}/revisions/{revision}",
search : "{host}/search?q={query}"
}
};
var convertTimestamp, supplant;
// host (optional) is the URI of the originating TiddlyWeb instance
tw.Resource = function(type, host) {
if(arguments.length) { // initialization
this._type = type;
if(host !== false) {
this.host = host !== undefined ? host.replace(/\/$/, "") : null;
}
}
};
$.extend(tw.Resource.prototype, {
// retrieves resource from server
// callback is passed resource, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
// filters is an optional filter string (e.g. "select=tag:foo;limit=5")
get: function(callback, errback, filters) {
var uri = this.route();
if(filters) {
var separator = uri.indexOf("?") === -1 ? "?" : ";";
uri += separator + filters;
}
var self = this;
return $.ajax({
url: uri,
type: "GET",
dataType: "json",
success: function(data, status, xhr) {
var resource = self.parse(data);
resource.etag = xhr.getResponseHeader("Etag");
callback(resource, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
});
},
// sends resource to server
// callback is passed data, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
put: function(callback, errback) {
var self = this;
var options = {
url: this.route(),
type: "PUT",
contentType: "application/json",
data: JSON.stringify(this.baseData()),
success: function(data, status, xhr) {
callback(self, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
};
if(this.ajaxSetup) {
this.ajaxSetup(options);
}
return $.ajax(options);
},
// deletes resource on server
// callback is passed data, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
"delete": function(callback, errback) {
var self = this;
var options = {
url: this.route(),
type: "DELETE",
success: function(data, status, xhr) {
callback(self, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
};
if(this.ajaxSetup) {
this.ajaxSetup(options);
}
return $.ajax(options);
},
// returns an object carrying only the essential information of the resource
baseData: function() {
var data = {},
self = this;
$.each(this.data, function(i, item) {
var value = self[item];
if(value !== undefined) {
data[item] = value;
}
});
return data;
},
// returns corresponding instance from a raw object (if applicable)
parse: function(data) {
return data;
},
// list of accepted keys in serialization
data: [],
// returns resource's URI
route: function() {
return supplant(tw.routes[this._type], this);
}
});
var Container = function(type, name, host) {
if(arguments.length) { // initialization
tw.Resource.apply(this, [type, host]);
this.name = name;
this.desc = "";
this.policy = new tw.Policy({});
}
};
Container.prototype = new tw.Resource();
$.extend(Container.prototype, {
tiddlers: function() {
return new tw.TiddlerCollection(this);
},
parse: function(data) {
var type = tw._capitalize(this._type),
container = new tw[type](this.name, this.host);
data.policy = new tw.Policy(data.policy);
return $.extend(container, data);
},
data: ["desc", "policy"]
});
// attribs is an object whose members are merged into the instance (e.g. query)
tw.Collection = function(type, host, attribs) {
if(arguments.length) { // initialization
tw.Resource.apply(this, [type, host]);
$.extend(this, attribs);
}
};
tw.Collection.prototype = new tw.Resource();
tw.TiddlerCollection = function(container, tiddler) {
if(arguments.length) { // initialization
tw.Collection.apply(this, [tiddler ? "revisions" : "tiddlers"]);
this.container = container || null;
this.tiddler = tiddler || null;
}
};
tw.TiddlerCollection.prototype = new tw.Collection();
$.extend(tw.TiddlerCollection.prototype, {
parse: function(data) {
var container = this.container;
return $.map(data, function(item, i) {
var tiddler = new tw.Tiddler(item.title, container),
bag = item.bag;
tiddler = tw.Tiddler.prototype.parse.apply(tiddler, [item]);
if(!tiddler.bag && bag) { // XXX: bag always present!?
tiddler.bag = new tw.Bag(bag, container.host);
}
if(!tiddler.recipe && item.recipe) {
tiddler.recipe = new tw.Recipe(item.recipe, container.host);
}
delete item.recipe;
return $.extend(tiddler, item);
});
},
route: function() {
var params = this.container;
if(this.tiddler) {
var container = this.tiddler.bag || this.tiddler.recipe;
params = {
_type: container._type,
host: container.host,
name: container.name,
title: this.tiddler.title
};
}
return supplant(tw.routes[this._type], params);
}
});
tw.Search = function(query, host) {
tw.Collection.apply(this, ["search", host]);
this.query = query;
};
tw.Search.prototype = new tw.Collection();
$.extend(tw.Search.prototype, {
parse: function(data) {
this.container = { // XXX: hacky
_type: "bag",
host: this.host
};
var tiddlers = tw.TiddlerCollection.prototype.parse.apply(this, arguments);
delete this.container;
return tiddlers;
}
});
// title is the name of the tiddler
// container (optional) is an instance of either Bag or Recipe
// optionally accepts a single object representing tiddler attributes
tw.Tiddler = function(title, container) {
tw.Resource.apply(this, ["tiddler", false]);
this.title = title;
this.bag = container && container._type === "bag" ? container : null;
this.recipe = container && container._type === "recipe" ? container : null;
var self = this;
$.each(this.data, function(i, item) {
self[item] = undefined; // exposes list of standard attributes for inspectability
});
if(title && title.title) { // title is an object of tiddler attributes
$.extend(this, title);
}
};
tw.Tiddler.prototype = new tw.Resource();
$.extend(tw.Tiddler.prototype, {
revisions: function() {
return new tw.TiddlerCollection(this.bag || this.recipe, this);
},
route: function() {
var container = this.bag || this.recipe;
var params = $.extend({}, this, {
host: container ? container.host : null,
_type: this.bag ? "bag" : (this.recipe ? "recipe" : null),
name: container ? container.name : null
});
return supplant(tw.routes[this._type], params);
},
parse: function(data) {
var tiddler = new tw.Tiddler(this.title),
container = this.bag || this.recipe;
if(data.bag) {
tiddler.bag = new tw.Bag(data.bag, container.host);
delete data.bag;
}
delete data.recipe;
tiddler.created = data.created ? convertTimestamp(data.created) : new Date();
delete data.created;
tiddler.modified = data.modified ? convertTimestamp(data.modified) : new Date();
delete data.modified;
if(this.recipe) {
tiddler.recipe = this.recipe;
}
return $.extend(tiddler, data);
},
data: ["created", "creator", "modifier", "modified", "tags", "type", "text",
"fields"],
ajaxSetup: function(options) {
var self = this;
if(this.etag && (options.type === "PUT" || options.type === "DELETE")) {
options.beforeSend = function(xhr) {
xhr.setRequestHeader("If-Match", self.etag);
};
}
if(options.type === "PUT") {
var callback = options.success;
options.success = function(data, status, xhr) {
var loc = xhr.getResponseHeader("Location"),
etag = xhr.getResponseHeader("Etag");
if(loc && etag) {
self.etag = etag;
if(!self.bag) {
var bag = loc.split("/bags/").pop().split("/")[0];
self.bag = new tw.Bag(bag, self.recipe.host);
}
callback(self, status, xhr);
} else { // IE
self.get(callback, options.error);
}
};
}
}
});
tw.Revision = function(id, tiddler) {
var container = tiddler.bag || tiddler.recipe;
tw.Tiddler.apply(this, [tiddler.title, container]);
this._type = "revision";
this.revision = id;
};
tw.Revision.prototype = new tw.Tiddler();
$.extend(tw.Revision.prototype, {
revisions: false,
data: false,
put: false,
"delete": false
});
tw.Bag = function(name, host) {
Container.apply(this, ["bag", name, host]);
};
tw.Bag.prototype = new Container();
tw.Recipe = function(name, host) {
Container.apply(this, ["recipe", name, host]);
this.recipe = [];
};
tw.Recipe.prototype = new Container();
$.extend(tw.Recipe.prototype, {
data: ["recipe"].concat(Container.prototype.data)
});
tw.Policy = function(constraints) { // TODO: validation?
var self = this;
$.each(this.constraints, function(i, item) {
self[item] = constraints[item];
});
};
tw.Policy.prototype.constraints = ["read", "write", "create", "delete",
"manage", "accept", "owner"];
/*
* utilities
*/
tw._capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
// convert YYYYMMDDhhmmss timestamp to Date instance
convertTimestamp = function(t) {
if (t.match(/^\d{12,17}$/)) {
return new Date(Date.UTC(
parseInt(t.substr(0, 4), 10),
parseInt(t.substr(4, 2), 10) - 1,
parseInt(t.substr(6, 2), 10),
parseInt(t.substr(8, 2), 10),
parseInt(t.substr(10, 2), 10),
parseInt(t.substr(12, 2) || "0", 10),
parseInt(t.substr(14, 3) || "0", 10)
));
} else {
return new Date(Date.parse(t));
}
};
// adapted from Crockford (http://javascript.crockford.com/remedial.html)
supplant = function(str, obj) {
return str.replace(/{([^{}]*)}/g, function (a, b) {
var r = obj[b];
r = typeof r === "string" || typeof r === "number" ? r : a;
return $.inArray(b, ["host", "query"]) !== -1 ? r : encodeURIComponent(r); // XXX: special-casing
});
};
return tw;
}(jQuery));
//}}}
|Date|Users|Spaces|
|20110401|1285|2786|
|20110402|1293|2809|
|20110403|1299|2820|
|20110404|1310|2833|
|20110405|1321|2854|
|20110406|1328|2864|
|20110407|1342|2883|
|20110408|1352|2895|
|20110409|1357|2906|
|20110410|1363|2913|
|20110411|1365|2916|
|20110412|1381|2937|
|20110413|1396|2960|
|20110414|1403|2972|
|20110415|1409|2986|
|20110416|1415|2992|
|20110417|1422|3002|
|20110418|1426|3007|
|20110419|1432|3017|
|20110420|1445|3032|
|20110421|1451|3043|
|20110422|1456|3049|
|20110423|1463|3058|
|20110424|1468|3066|
|20110425|1474|3078|
|20110426|1481|3086|
|20110427|1491|3104|
|20110428|1501|3118|
|20110429|1507|3128|
|20110430|1514|3139|
|Date|Users|Spaces|
|20110501|1520|3151|
|20110502|1525|3158|
|20110503|1528|3169|
|20110504|1532|3175|
|20110505|1542|3190|
|20110506|1550|3202|
|20110507|1560|3217|
|20110508|1563|3221|
|20110509|1564|3223|
|20110510|1572|3235|
|20110511|1584|3255|
|20110512|1594|3269|
|20110513|1600|3278|
|20110514|1606|3292|
|20110515|1616|3307|
|20110516|1617|3309|
|20110517|1625|3320|
|20110518|1630|3325|
|20110519|1640|3341|
|20110520|1652|3359|
|20110521|1660|3372|
|20110522|1669|3381|
|20110523|1680|3395|
|20110524|1685|3402|
|20110525|1699|3418|
|20110526|1716|3437|
|20110527|1735|3464|
|20110528|1743|3472|
|20110529|1754|3487|
|20110530|1761|3497|
|20110531|1771|3509|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20121201|6281|9496|668|755|311.1|8321.71|
|20121202|6287|9502|171|299|318.9|2532.8|
|20121203|6293|9510|169|261|313|15078.2|
|20121204|6306|9525|500|592|304.9|2464.89|
|20121205|6309|9530|130|239|314.6|230.37|
|20121206|6318|9540|486|557|309.2|2676.49|
|20121207|6324|9548|3191|3290|316.3|225.64|
|20121208|6328|9555|128|220|310.8|6987.59|
|20121209|6330|9557|84|211|320.3|7256.83|
|20121210|6337|9565|216|1352|308.9|2532.47|
|20121211|6345|9574|195|313|324.5|2515.01|
|20121212|6348|9577|199|564|310.8|2613.25|
|20121213|6353|9584|619|680|316.9|3445.34|
|20121214|6361|9593|199|266|316.8|2522.74|
|20121215|6366|9599|1125|1219|325.7|403.18|
|20121216|6369|9602|272|353|319.3|7430.16|
|20121217|6373|9607|180|251|319.7|2619.2|
|20121218|6376|9610|81|186|319.1|2712.72|
|20121219|6381|9616|90|194|316.5|2717.98|
|20121220|6384|9619|194|352|319.8|7489.38|
|20121221|6387|9622|149|281|318.1|2620.24|
|20121222|6389|9625|368|519|2966.4|233.49|
|20121223|6392|9628|216|320|498.9|2604.14|
|20121224|6395|9632|197|255|318.5|2592.12|
|20121225|6397|9634|116|1629|312.2|7324.65|
|20121226|6402|9641|180|324|322.3|2652.92|
|20121227|6410|9648|176|502|318.6|2713.99|
|20121228|6419|9657|152|401|325|2547.97|
|20121229|6422|9660|278|353|324.2|8524.68|
|20121230|6424|9662|69|153|318|2677.97|
|20121231|6427|9667|328|601|850.4|2664.26|
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AP8zZgAAAGYA//8zAADMMwD/mTMAAGYzAP8zMwAAADMAzP8AAADMAADMmQAAAGYAAMwzAAAAAADuzAAA3QAAALvMAACqAAAAiMwAAHcAAABVmQAARAAAACKZAAARAADuAJkA3QAAALsAmQCqAAAAiACZAHcAAABVAJkARAAAACIAZgARAADuAABm3QAAALsAAGaqAAAAiAAAZncAAABVAABmRAAAACIAAGYRAAAA7u7uM93d3QC7u7szqqqqAIiIiDN3d3cAVVVVM0RERAAiIiIzERERAAAAADMBAQEBAQEBAQEBpXl5eXl5eXl5eXmlAQEBAQEBAQEBAQEBAQEBAQEBgHl5eXl5eXl5eXl5eXl5gAEBAQEBAQEBAQEBAQEB/Xp5eXlVT04qKioqTk9VeXl5ev0BAQEBAQEBAQEBAaV5eXlPKioqKioqKioqKioqT3l5eaUBAQEBAQEBAQGAeXlVTioqKioqKioqKioqKioqTlV5eYABAQEBAQEBgHl5VSoqKioqKioqKioqKioqKioqKlV5eYABAQEBAaV5eVUqKioqKioqKioqKioqKioqKioqKlV5eaUBAQEBeXlVKioqKioqKioqKioqKioqKioqKioqKlV5eQEBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBeXlPKioqKioqKjEyMjIyMjIyMjEqKioqKioqT3l5AXp5eSoqKioqKioxMjIxBwcHBzEyMjEqKioqKioqeXl6eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl5eU8qKioqKioyMgcHBwcHBwcHBwcyMioqKioqKk95eXl5TioqKioqMTIxBwcHBwcHBwcHBzEyMSoqKioqTnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eSoqKioqKjEyBwcHBwcHBwcHBwcHMjEqKioqKip5eXl5KioqKioqMTIHBwcHBwcHBwcHBwcyMSoqKioqKnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eU4qKioqKjEyMQcHBwcHBwcHBwcxMjEqKioqKk55eXl5TyoqKioqKjIyBwcHBwcHBwcHBzIyKioqKioqT3l5eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl6eXkqKioqKioqMTIyMQcHBwcxMjIxKioqKioqKnl5egF5eU8qKioqKioqMTIyMjIyMjIyMSoqKioqKipPeXkBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBAXl5VSoqKioqKioqKioqKioqKioqKioqKipVeXkBAQEB+nl5VSoqKioqKioqKioqKioqKioqKioqVXl5+gEBAQEBenl5VSoqKioqKioqKioqKioqKioqKlV5eXoBAQEBAQEBeXl5VU4qKioqKioqKioqKioqKk5VeXl5AQEBAQEBAQEBenl5eU8qKioqKioqKioqKipPeXl5egEBAQEBAQEBAQEB+nl5eXlVT04qKioqTk9VeXl5efoBAQEBAQEBAQEBAQEBAXl5eXl5eXl5eXl5eXl5eXkBAQEBAQEBAQEBAQEBAQEBAQF6eXl5eXl5eXl5eXoBAQEBAQEBAQEB/+AH//+AAf/+AAB//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB///gB/8oAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAACAAAAAwAAAAMAAAADAAAABG1bSA61m3JXuqB4mbuhd8m9o3jqvaF4+b2hePm9o3jqu6F3ybqgeJm1m3JXbVtIDgAAAAQAAAADAAAAAwAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAGAAAACI98Wye0nXWavKF4876kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev+8oXjztJ11mo98WycAAAAIAAAABgAAAAUAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAQAAAAHAAAAChwcHBKulnGJvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+K6WcYkcHBwSAAAACgAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAEAAAADAAAABwAAAAtuYkUst552z76kev++pHr+1LuS//Latf/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/8tq1/9S7kv++pHr+vqR6/7eeds9uYkUsAAAACwAAAAcAAAADAAAAAQAAAAAAAAABAAAAAgAAAAQAAAAIi3hbNbqgd+a+pHr/xayD/+3Vr//85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr//FrIP/vqR6/7qgd+aJdVg0AAAACAAAAAQAAAACAAAAAQAAAAEAAAACAAAABIl8WSW8oXjlvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7yheOWJfFklAAAABAAAAAIAAAABAAAAAAAAAAFfXz8Iu6F4zL6kev/Msor/+uK+//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//rivv/Msor/vqR6/7uheMxfXz8IAAAAAQAAAAAAAAAAAAAAAbqid4K+pHr/xayD//ngvP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//fgvP/FrIP/vqR6/7qid4IAAAABAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAALuheJa+pHr/1LuS//zlwP/85cD//OXA//zlwP/85cD//OXA//riwP/Pq8f/r4HM/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HN/6+BzP/Pq8f/+uLA//zlwP/85cD//OXA//zlwP/85cD//OXA/9S5kv++pHr/u6F4lgAAAACii3MLvKF4876kev/y2rX//OXA//zlwP/85cD//OXA//zlwP/64sD/w5vJ/6+Bzf+vg83/w5vc/9W06v/dwPD/3cDw/9W06v/Dm9z/r4PN/6+Bzf/Dm8n/+uLA//zlwP/85cD//OXA//zlwP/85cD/8tq1/76kev+8oXjzootzC72feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVvaF4mL6kev/fxZ7//OXA//zlwP/85cD//OXA//zlwP/v08L/r4HM/6+Dzf/Wtev/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/r4PN/6+BzP/v08L//OXA//zlwP/85cD//OXA//zlwP/fxZ7/vqR6/72heJi8oXfIvqR6/+zUrv/85cD//OXA//zlwP/85cD//OXA/9Crx/+vgc3/w5vc/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Dm9z/r4HN/9Crx//85cD//OXA//zlwP/85cD//OXA/+zUrv++pHr/vKF3yL2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvaF4+b6kev/64r7//OXA//zlwP/85cD//OXA//zlwP+zhsz/r4HN/93A8P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/3cDw/6+Bzf+zhsz//OXA//zlwP/85cD//OXA//zlwP/64r7/vqR6/72hePm9oXj5vqR6//rivv/85cD//OXA//zlwP/85cD//OXA/7OGzP+vgc3/3cDw/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//dwPD/r4HN/7OGzP/85cD//OXA//zlwP/85cD//OXA//rivv++pHr/vaF4+b2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvKF3yL6kev/s1K7//OXA//zlwP/85cD//OXA//zlwP/Qq8f/r4HN/8Ob3P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/w5vc/6+Bzf/Qq8f//OXA//zlwP/85cD//OXA//zlwP/s1K7/vqR6/7yhd8i9oXiYvqR6/9/Fnv/85cD//OXA//zlwP/85cD//OXA/+/Twv+vgcz/r4PN/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9a16/+vg83/r4HM/+/Twv/85cD//OXA//zlwP/85cD//OXA/9/Fnv++pHr/vaF4mL2feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVootzC7yhePO+pHr/8tq1//zlwP/85cD//OXA//zlwP/85cD/+uLA/8Obyf+vgc3/r4PN/8Ob3P/VtOr/3cDw/93A8P/VtOr/w5vc/6+Dzf+vgc3/w5vJ//riwP/85cD//OXA//zlwP/85cD//OXA//Latf++pHr/vKF486KLcwsAAAAAu6N3l76kev/Uu5L//OXA//zlwP/85cD//OXA//zlwP/85cD/+uLA/8+rx/+vgcz/r4HN/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HM/8+rx//64sD//OXA//zlwP/85cD//OXA//zlwP/85cD/1LmS/76kev+7oXiWAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAAAAAAAC6oneCvqR6/8Wsg//54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/34Lz/xayD/76kev+6oneCAAAAAAAAAAAAAAAAAAAAAH9/VQa8oHjLvqR6/8yyiv/64r7//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/+uK+/8yyiv++pHr/vKB4y39/VQYAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh67o3nkvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7ujeeSyoW4eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALqbdim7o3nkvqR6/8Wsg//t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/t1a//xayD/76kev+7o3nkupt2KQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh68oHjLvqR6/76kev7Uu5L/8tq1//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/y2rX/1LmS/76kev6+pHr/vKB4y7Khbh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/VQa6oneCvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+Lqid4J/f1UGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l28gu6F4lryhePO+pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vKF487uheJa3l28gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAootzC72feFW9oXiYvKF3yL2jeOq9oXj5vaF4+b2jeOq8oXfIvaF4mL2feFWii3MLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/+AAf//4Af/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Reply</title>
<link rel="stylesheet" href="http://tiddlyspace.com/bags/benspa_public/tiddlers/bootvelcro.css">
<style>
html,
body {
overflow: hidden;
background-color: transparent;
}
#container {
/* prevent a fouc if no images present */
display: none;
}
.modal-header {
border-bottom: none;
padding: 5px 0 0;
position: absolute;
width: 100%;
background-color: #e0e0e0;
-webkit-border-radius: 6px 6px 0 0;
-moz-border-radius: 6px 6px 0 0;
border-radius: 6px 6px 0 0;
cursor: move;
}
.form-actions {
position: absolute;
bottom: 0;
box-sizing: border-box;
-moz-box-sizing: border-box;
width: 100%;
margin: 0;
border-radius: 0 0 6px 6px;
background-color: #e0e0e0;
border-top: 1px solid gray;
}
.form-actions input.btn {
width: auto;
float: right;
margin: 0 0.2em;
}
.closeBtn {
background-color: #DCE7F1 !important;
}
.primary {
background-color: #09F !important;
}
h1 {
margin-bottom: 9px;
margin-top: 9px;
}
body {
width: 100%;
height: 100%;
position: absolute;
}
.modal {
margin: 10px;
top: 0;
left: 0;
bottom: 0;
width: 510px;
position: absolute;
box-shadow: #444 0px 0px 10px 2px;
border-radius: 6px;
background-color: white;
border: 1px solid gray;
background-color: #F0F4F8;
}
label em {
cursor: pointer;
}
.modal-body {
overflow: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 65px 20px 67px;
background-color: transparent;
}
.nav-tabs {
padding-left: 1%;;
margin: 0;
width: 99%;
border-color: gray;
}
.nav-tabs > li {
cursor: pointer;
}
.nav-tabs > li > a {
line-height: 2.4em;
font-weight: bold;
font-size: 100%;
}
.nav-tabs > li.active > a{
background-color: #F0F4F8;
border-color: gray;
border-bottom-color: #F0F4F8;
}
.active {
display: block;
}
input,
textarea,
select,
.uneditable-input {
color: #606060;
}
.imagePicker {
-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
border: 1px solid #CCC;
height: 110px;
overflow: auto;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
margin-left: 0;
}
.imagePicker img {
margin: 5px;
border: 2px solid transparent;
}
.imagePicker .current {
border: 2px dotted #555;
}
label {
font-weight: bold;
}
.form-actions label {
float: left;
margin-top: 0.75em;
}
fieldset input,
fieldset textarea {
width: 90%;
border-color: gray;
}
@media all and (max-width: 550px) {
.modal {
width: 95%;
}
}
#help {
position: absolute;
border: 0;
right: 4px;
top: 5px;
text-indent: -9999px;
color: transparent;
height: 16px;
width: 16px;
background: none;
background-image: url(http://tiddlyspace.com/bags/common/tiddlers/help.png);
background-repeat: no-repeat;
background-color: white;
z-index: 2;
border-radius: 10px;
}
#help-info {
padding: 0;
border: 1px solid gray;
width: 60%;
height: 50px;
color: #404040;
background-color: white;
position: absolute;
top: 5px;
right: 5px;
z-index: 1;
cursor: auto;
border-radius: 5px;
}
#help-info p {
padding: 10px 25px;
margin-bottom: 0;
}
</style>
</head>
<body>
<div id="container">
<form action="#" class="modal">
<div class="modal-header">
<button id="help">help</button>
<div id="help-info" style="display:none;"><p>
Found something interesting? Write about it in your own space. <a href="http://docs.tiddlyspace.com/Reply to this Tiddler" target="_blank">Find out more</a>
</p></div>
<ul class="nav nav-tabs" data-tabs="tabs">
<li class="active" data-tab-name="post"><a href="#postForm">Reply</a></li>
</ul>
</div>
<fieldset id="postForm" class="modal-body">
<label>Title
<input type="text" name="title">
</label>
<input type="hidden" name="url">
<label>Post
<textarea name="text" rows="8"></textarea>
</label>
<label>Tags
<input type="text" name="tags" value="">
</label>
</fieldset>
<div class="form-actions">
<label class="checkbox">
<input type="checkbox" name="private" val="private">
keep private
</label>
<input type="submit" class="btn primary btn-large" value="Done">
<input type="button" class="btn btn-large closeBtn" value="Cancel">
</div>
</form>
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="http://tiddlyspace.com/bags/tiddlyspace/tiddlers/chrjs"></script>
<script type="text/javascript" src="/bags/common/tiddlers/_reply.js"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Account</title>
<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
<link href="/bags/common/tiddlers/jquery-ui.custom.css" type='text/css' rel='stylesheet' >
</head>
<body>
<div id="container">
<div class="main section">
<a class="app" href="/">home</a>
<div class="left">
<div id="siteiconArea">
<h2>User Icon</h2>
<div>
<img id="siteicon" class="siteicon">
<form id="upload" method="POST" enctype="multipart/form-data">
<input type="hidden" name="title" value="SiteIcon" />
<input type="hidden" name="tags" value="excludeLists">
<input type="hidden" name="csrf_token" class="csrf" />
<input type="file" name="file" accept="image/*" />
<input type="submit" value="upload" />
</form>
<div id="dropzone">Drop file here
<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
</div>
</div>
</div>
<h2>Find Space</h2>
<form class="spaceSearch">
<input class="inputBox" type="text" placeholder="find space" />
<a href="http://docs.tiddlyspace.com/What%20is%20a%20Space%3F" class="help"
title="What is a space?">What is a space?</a>
<button>view all</button>
</form>
<div class='list-container'>
You are a member of the following spaces:
<ul class='ts-space-search'>
</ul>
</div>
<h2>Create New Space</h2>
<form class="ts-spaces">
<input class="inputBox" type="text" name="spacename" placeholder="space name"><span class="hostSuffix">.tiddlyspace.com</span>
<input type="submit" value="Create Space" />
</form>
</div>
<div class="right">
<h2>Change Password</h2>
<form class="ts-password">
<input class="inputBox" placeholder="existing password" type="password" name="password">
<input class="inputBox" placeholder="new password" type="password" name="new_password">
<input class="inputBox" placeholder="new password" type="password" name="new_password_confirm">
<input type="submit" value="Change password">
</form>
<h2>OpenID</h2>
<h3>Why OpenID?</h3>
<a href="http://openid.net/"><img src="/bags/common/tiddlers/openid.png" alt="openid" ></a><br />
Use just one username and password across hundreds of OpenID-enabled sites.<br />
It's an open standard.<br />
<a href="http://openid.net/what/">learn more</a>
<ul class="ts-identities"></ul>
<form class="ts-openid" target="_top">
<div>
Add an openid:
</div>
<input class="inputBox" type="text" name="openid" placeholder="your openid" />
<input type="submit" value="Register" />
<a href="http://openid.net/get-an-openid/" class="help"
title="What is an open id?">What is an open id?</a>
</form>
</div>
<div class="clear"></div>
</div>
</div>
<script src="/bags/common/tiddlers/backstage.js"></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src="/bags/common/tiddlers/jquery-ui.custom.js"></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src='/bags/common/tiddlers/ts.js'></script>
<script src="/status.js"></script>
<script type="text/javascript">
/*
* jQuery UI Autocomplete HTML Extension
*
* Copyright 2010, Scott González (http://scottgonzalez.com)
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* http://github.com/scottgonzalez/jquery-ui-extensions
*/
(function( $ ) {
var proto = $.ui.autocomplete.prototype,
initSource = proto._initSource;
function filter( array, term ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
return $.grep( array, function(value) {
return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
});
}
$.extend( proto, {
_initSource: function() {
if ( this.options.html && $.isArray(this.options.source) ) {
this.source = function( request, response ) {
response( filter( this.options.source, request.term ) );
};
} else {
initSource.call( this );
}
},
_renderItem: function( ul, item) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
.appendTo( ul );
}
});
})( jQuery );
/***
_accounts application specific javascript
***/
var link;
ts.init(function(ts) {
if(ts.user.anon) { // redirect to homepage when user not logged in
window.location = ts.getHost();
} else if(ts.user.name === ts.currentSpace){
initSiteIconUpload(ts.user.name);
} else {
link = $("<a />").attr("href", ts.getHost(ts.user.name) + "/_account").text("Change User Icon");
$("#siteiconArea div").empty().append(link);
}
$(".hostSuffix").text("." + ts.getHost("").split("//")[1]);
ts.getSpaces(function(spaces) {
$("<div class='info' />").text("You have " + spaces.length + " spaces.").insertBefore($(".spaceSearch")[0]);
$("form.spaceSearch input").autocomplete({
html: true,
source: function(req, response) {
ts.getSpaces(function(spaces) {
var selected = [];
for(var i = 0; i < spaces.length; i++) {
var space = spaces[i];
if(space.name.indexOf(req.term) > -1) {
var host = ts.getHost(space.name) ;
var img = host + "/SiteIcon";
selected.push({
value: space.name,
label: '<a href="' + host + '" target="_parent" class="autocompleteLink"><img src="' + img + '" style="height:24px;width:auto;max-height:24px;max-width:24px;"/>' + space.name + '</a>'
});
}
}
response(selected);
});
},
select: function(event, ui) {
window.top.location = ts.getHost(ui.item.value);
}
});
var $ul = $('.ts-space-search');
$.each(spaces, function(i, space) {
$ul.append($('<li/>').html($('<a/>').attr('href', space.uri)
.text(space.name)));
});
$('form.spaceSearch button').click(function(ev) {
$('.list-container').slideToggle('fast');
ev.preventDefault();
return false;
});
});
});
if(window != window.top) {
$("html").addClass("iframeMode");
$("a").live("click",function(ev) {
$(ev.target).attr("target", "_parent");
});
}
</script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130101|6427|9668|46|123|321.3|265.43|
|20130102|6435|9679|415|556|326.3|2870.93|
|20130103|6437|9681|192|989|324.4|2587.87|
|20130104|6439|9685|259|404|397.4|2828.7|
|20130105|6442|9689|425|744|315.4|254.83|
|20130106|6444|9692|1015|1092|324.3|2516.1|
|20130107|6451|9705|216|323|664.2|6388.47|
|20130108|6458|9713|240|365|311.7|2692.42|
|20130109|6462|9717|928|1106|317|7895.48|
|20130110|6469|9732|261|347|312.9|2539.79|
|20130111|6473|9738|314|394|317.9|2493.77|
|20130112|6479|9746|197|276|311.9|7040.26|
|20130113|6482|9749|176|293|318|2620.36|
|20130114|6492|9762|179|327|316.5|2555.05|
|20130115|6502|9774|383|533|318|2702.77|
|20130116|6515|9788|459|570|313.3|2616.4|
|20130117|6525|9802|453|631|321|12858.8|
|20130118|6527|9809|666|794|314.8|2705.77|
|20130119|6527|9811|65|150|320.1|2714.4|
|20130120|6529|9815|102|157|316.8|2627.85|
|20130121|6537|9824|603|715|318.8|7349.58|
|20130122|6562|9870|680|870|323.2|10353.4|
|20130123|6571|9881|300|445|320.5|2607.19|
|20130124|6579|9896|655|756|324|7862.56|
|20130125|6584|9904|199|307|322.2|3160.22|
|20130126|6585|9908|253|347|310.1|2839.41|
|20130127|6592|9915|178|264|321.6|2677.86|
|20130128|6599|9922|2605|2744|334|2661.46|
|20130129|6605|9930|379|543|336.4|2856.58|
|20130130|6612|9938|447|575|315.3|2610.55|
|20130131|6618|9947|352|525|328.7|190.8|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>TiddlySpace Apps</title>
<link rel="stylesheet" href="/bags/common/tiddlers/reset.css" />
<link rel="stylesheet" href="/bags/common/tiddlers/appspage.css" />
<!--[if lt IE 7 ]>
<link rel="stylesheet" href="/bags/common/tiddlers/appspageie6.css" />
<![endif]-->
</head>
<body>
<div id="wrapper">
<div id="TSbar"></div>
<div id="main-content">
<div id="space-details">
<a href="/_space"><img class="siteicon"></a>
<div id="title-subtitle">
<h1 class="spaceaddress">
<span class="spaceName"></span><span class="hostName"></span>
</h1>
<p class="tagline"><span class="subTitle"></span><a class="managespaces" href="/_space">manage space</a></p>
</div>
</div>
<div id="holder">
<div id="appswitcher-wrapper">
<div id="appswitcher">
<h2>Your Apps</h2>
<ul id="app-list">
<li class="htmlserialisation">
<a href="/tiddlers.html?select=tag:!excludeLists;sort=-modified">
<img src="/bags/common/tiddlers/browse_read_blue.png" alt="Icon for the HTML Serialisation" class="app-img" />
BROWSE
</a>
</li>
<li class="tiddlywiki">
<a href="/tiddlers.wiki">
<img src="/bags/common/tiddlers/tiddlywiki2_blue.png" alt="Icon for TiddlyWiki" class="app-img" />
TIDDLYWIKI
</a>
</li>
</ul>
<div id="addapp">
<button class="inactive">Add More!</button>
</div>
</div>
<div id="app-desc">
<ul>
<li class="htmlserialisationdesc"><p>an easy to understand HTML representation of your content.</p></li>
<li class="tiddlywikidesc"><p>use TiddlyWiki to create, edit and organise your content.</p></li>
</ul>
</div>
<div style="clear: both;"></div>
</div>
</div>
</div>
<div id="footer"><!-- ie doesn't support footer tag -->
<div id="footer-content">
<div class="links">
<a href="http://blog.tiddlyspace.com">blog</a>
<a href="http://featured.tiddlyspace.com">featured</a>
<a href="http://docs.tiddlyspace.com">documentation</a>
<a href="https://github.com/TiddlySpace/tiddlyspace">source</a>
</div>
<p>TiddlySpace 2011, created by <a href="http://osmosoft.com">Osmosoft</a></p>
</div>
</div>
</div>
<script type="text/javascript" src="/bags/common/tiddlers/backstage.js"></script>
<script type="text/javascript" src="/bags/common/tiddlers/jquery.js"></script>
<script type="text/javascript" src="/bags/tiddlyspace/tiddlers/chrjs"></script>
<script type="text/javascript" src="/bags/common/tiddlers/chrjs-store.js"></script>
<script type="text/javascript" src="/bags/common/tiddlers/jquery-json.js"></script>
<script type="text/javascript" src="/bags/common/tiddlers/appspage.js"></script>
</body>
</html>
/***
|''Name''|TiddlyWebConfig|
|''Description''|configuration settings for TiddlyWebWiki|
|''Author''|FND|
|''Version''|1.3.2|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/TiddlyWebConfig.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Requires''|TiddlyWebAdaptor ServerSideSavingPlugin|
|''Keywords''|serverSide TiddlyWeb|
!Code
***/
//{{{
(function($) {
if(!config.extensions.ServerSideSavingPlugin) {
throw "Missing dependency: ServerSideSavingPlugin";
}
if(!config.adaptors.tiddlyweb) {
throw "Missing dependency: TiddlyWebAdaptor";
}
if(window.location.protocol != "file:") {
config.options.chkAutoSave = true;
}
var adaptor = tiddler.getAdaptor();
var recipe = tiddler.fields["server.recipe"];
var workspace = recipe ? "recipes/" + recipe : "bags/common";
var plugin = config.extensions.tiddlyweb = {
host: tiddler.fields["server.host"].replace(/\/$/, ""),
username: null,
status: {},
getStatus: null, // assigned later
getUserInfo: function(callback) {
this.getStatus(function(status) {
callback({
name: plugin.username,
anon: plugin.username ? plugin.username == "GUEST" : true
});
});
},
hasPermission: function(type, tiddler) {
var perms = tiddler.fields["server.permissions"];
if(perms) {
return perms.split(", ").contains(type);
} else {
return true;
}
}
};
config.defaultCustomFields = {
"server.type": tiddler.getServerType(),
"server.host": plugin.host,
"server.workspace": workspace
};
// modify toolbar commands
config.shadowTiddlers.ToolbarCommands = config.shadowTiddlers.ToolbarCommands.
replace("syncing ", "revisions syncing ");
config.commands.saveTiddler.isEnabled = function(tiddler) {
return plugin.hasPermission("write", tiddler) && !tiddler.isReadOnly();
};
config.commands.deleteTiddler.isEnabled = function(tiddler) {
return !readOnly && plugin.hasPermission("delete", tiddler);
};
// hijack option macro to disable username editing
var _optionMacro = config.macros.option.handler;
config.macros.option.handler = function(place, macroName, params, wikifier,
paramString) {
if(params[0] == "txtUserName") {
params[0] = "options." + params[0];
var self = this;
var args = arguments;
args[0] = $("<span />").appendTo(place)[0];
plugin.getUserInfo(function(user) {
config.macros.message.handler.apply(self, args);
});
} else {
_optionMacro.apply(this, arguments);
}
};
// hijack isReadOnly to take into account permissions and content type
var _isReadOnly = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
return _isReadOnly.apply(this, arguments) ||
!plugin.hasPermission("write", this);
};
var getStatus = function(callback) {
if(plugin.status.version) {
callback(plugin.status);
} else {
var self = getStatus;
if(self.pending) {
if(callback) {
self.queue.push(callback);
}
} else {
self.pending = true;
self.queue = callback ? [callback] : [];
var _callback = function(context, userParams) {
var status = context.serverStatus || {};
for(var key in status) {
if(key == "username") {
plugin.username = status[key];
config.macros.option.propagateOption("txtUserName",
"value", plugin.username, "input");
} else {
plugin.status[key] = status[key];
}
}
for(var i = 0; i < self.queue.length; i++) {
self.queue[i](plugin.status);
}
delete self.queue;
delete self.pending;
};
adaptor.getStatus({ host: plugin.host }, null, _callback);
}
}
};
(plugin.getStatus = getStatus)(); // XXX: hacky (arcane combo of assignment plus execution)
})(jQuery);
//}}}
/***
|''Name''|TiddlySpaceConfig|
|''Version''|0.7.7|
|''Description''|TiddlySpace configuration|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceConfig.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlyWebConfig ServerSideSavingPlugin TiddlyFileImporter|
!Code
***/
//{{{
(function($) {
var tweb = config.extensions.tiddlyweb;
var recipe = config.defaultCustomFields["server.workspace"].split("recipes/")[1];
var currentSpace; // assigned later
var disabledTabs = [];
var coreBags = ["system", "tiddlyspace"];
var systemSpaces = ["plugins", "info", "images", "theme"];
systemSpaces = $.map(systemSpaces, function(item, i) {
return "system-%0_public".format(item);
});
// hijack search macro to add custom attributes for mobile devices
var _search = config.macros.search.handler;
config.macros.search.handler = function(place, macroName, params) {
_search.apply(this, arguments);
$(".searchField:input", place).
attr({ autocapitalize: "off", autocorrect: "off" });
};
// arg is either a container name or a tiddler object
// if fuzzy is truthy, space may be inferred from workspace (for new tiddlers)
// returns space object or false
var determineSpace = function(arg, fuzzy) {
if(typeof arg == "string") { // container name
var space = split(arg, "_", "r");
return ["public", "private"].contains(space.type) ? space : false;
} else if(arg) { // tiddler
var container = determineContainer(arg, fuzzy);
return container ? determineSpace(container.name, fuzzy) : false;
} else {
return false;
}
};
// if fuzzy is truthy, container may be inferred from workspace for new tiddlers
// returns container object or false
var determineContainer = function(tiddler, fuzzy) { // TODO: expose?
var bag = tiddler.fields["server.bag"];
var recipe = tiddler.fields["server.recipe"]; // XXX: unused/irrelevant/redundant!?
if(bag) {
return { type: "bag", name: bag };
} else if(recipe) {
return { type: "recipe", name: recipe };
} else if(fuzzy) { // new tiddler
var workspace = tiddler.fields["server.workspace"];
if(workspace) {
var container = split(workspace, "/", "l");
return ["bags", "recipes"].contains(container.type) ? container : false;
} else {
return false;
}
} else {
return false;
}
};
// hijack removeTiddlerCallback to restore tiddler from recipe cascade -- TODO: move into TiddlyWebWiki?
var sssp = config.extensions.ServerSideSavingPlugin;
var _removeTiddlerCallback = sssp.removeTiddlerCallback;
sssp.removeTiddlerCallback = function(context, userParams) {
var title = context.tiddler.title;
var recipe = context.tiddler.fields["server.recipe"];
_removeTiddlerCallback.apply(this, arguments);
if(recipe) {
context.workspace = "recipes/" + recipe;
var callback = function(context, userParams) {
if(context.status) {
var dirty = store.isDirty();
store.saveTiddler(context.tiddler).clearChangeCount();
store.setDirty(dirty);
} else {
store.notify(title, true);
}
};
context.adaptor.getTiddler(title, context, null, callback);
}
};
// splits a string once using delimiter
// mode "l" splits at the first, "r" at the last occurrence
// returns an object with members type and name
var split = function(str, sep, mode) {
mode = mode == "r" ? "pop" : "shift"; // TODO: use +/-1 instead of "l"/"r"?
var arr = str.split(sep);
var type = arr.length > 1 ? arr[mode]() : null;
return { type: type, name: arr.join(sep) };
};
var plugin = config.extensions.tiddlyspace = {
currentSpace: determineSpace(recipe),
coreBags: coreBags.concat(systemSpaces),
determineSpace: determineSpace,
isValidSpaceName: function(name) {
return name.match(/^[a-z][0-9a-z\-]*[0-9a-z]$/) ? true : false;
},
getCurrentBag: function(type) {
return "%0_%1".format(currentSpace, type);
},
getCurrentWorkspace: function(type) {
return "bags/" + this.getCurrentBag(type);
},
// returns the URL for a space's avatar (SiteIcon) based on a server_host
// object and an optional space name
// optional nocors argument prevents cross-domain URLs from being generated
getAvatar: function(host, space, nocors) {
if(space && typeof space != "string") { // backwards compatibility -- XXX: deprecated
space = space.name;
}
var subdomain = nocors ? currentSpace : space;
host = host ? this.getHost(host, subdomain) : "";
var bag = space ? "%0_public".format(space) : "tiddlyspace";
return "%0/bags/%1/tiddlers/SiteIcon".format(host, bag);
},
// returns the URL based on a server_host object (scheme, host, port) and an
// optional subdomain
getHost: function(host, subdomain) {
if(host === undefined) { // offline
tweb.status.server_host = {}; // prevents exceptions further down the stack -- XXX: hacky workaround, breaks encapsulation
return null;
}
subdomain = subdomain ? subdomain + "." : "";
var url = "%0://%1%2".format(host.scheme, subdomain, host.host);
var port = host.port;
if(port && !["80", "443"].contains(port)) {
url += ":" + port;
}
return url;
},
disableTab: function(tabTiddler) {
if(typeof(tabTiddler) == "string") {
disabledTabs.push(tabTiddler);
} else {
for(var i = 0; i < tabTiddler.length; i++) {
plugin.disableTab(tabTiddler[i]);
}
}
},
checkSyncStatus: function(tiddler) {
if(tiddler) {
var title = typeof(tiddler) === "string" ? tiddler : tiddler.title;
var el = story.getTiddler(title) || false;
if(el) {
refreshElements(el);
}
}
},
isDisabledTab: function(tabTitle) {
var match = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])", "mg").exec(tabTitle);
var tabIdentifier = match ? match[1] : tabTitle;
return disabledTabs.contains(tabIdentifier);
},
getCSRFToken: window.getCSRFToken || null // this may not have been processed yet
};
currentSpace = plugin.currentSpace.name;
tweb.serverPrefix = tweb.host.split("/")[3] || ""; // XXX: assumes root handler
tweb.getStatus(function(status) {
var url = plugin.getHost(status.server_host);
tweb.status.server_host.url = url;
config.messages.tsVersion = status.version;
});
if(window.location.protocol == "file:") {
// enable AutoSave by default
config.options.chkAutoSave = config.options.chkAutoSave === undefined ?
true : config.options.chkAutoSave;
} else {
// set global read-only mode based on membership heuristics
var indicator = store.getTiddler("SiteTitle") || tiddler;
readOnly = !(recipe.split("_").pop() == "private" ||
tweb.hasPermission("write", indicator));
// replace TiddlyWiki's ImportTiddlers due to cross-domain restrictions
if(config.macros.fileImport) {
$.extend(config.macros.importTiddlers, config.macros.fileImport);
}
}
// hijack saveChanges to ensure SystemSettings is private by default
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
if(tiddlers && tiddlers.length == 1 &&
tiddlers[0] && tiddlers[0].title == "SystemSettings") {
var fields = tiddlers[0].fields;
delete fields["server.recipe"];
fields["server.bag"] = plugin.getCurrentBag("private");
fields["server.workspace"] = plugin.getCurrentWorkspace("private");
}
return _saveChanges.apply(this, arguments);
};
// ensure backstage is always initialized
// required to circumvent TiddlyWiki's read-only based handling
config.macros.backstageInit = {
init: function() {
showBackstage = true;
}
};
// disable evaluated macro parameters for security reasons
config.evaluateMacroParameters = "none";
var _parseParams = String.prototype.parseParams;
String.prototype.parseParams = function(defaultName, defaultValue, allowEval,
noNames, cascadeDefaults) {
if(config.evaluateMacroParameters == "none") {
arguments[2] = false;
}
return _parseParams.apply(this, arguments);
};
var _tabsMacro = config.macros.tabs.handler;
config.macros.tabs.handler = function(place, macroName, params) {
var newParams = [params[0]]; // keep cookie name
for(var i = 1; i < params.length; i += 3) {
var tabTitle = params[i + 2];
if(!plugin.isDisabledTab(tabTitle)){
newParams = newParams.concat(params[i], params[i + 1], tabTitle);
}
}
_tabsMacro.apply(this, [place, macroName, newParams]);
};
// disable ControlView for XHRs by default
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader("X-ControlView", "false");
}
});
// TiddlyWeb adaptor currently still uses httpReq, which needs extra magic -- XXX: obsolete this!
var _httpReq = httpReq;
httpReq = function(type, url, callback, params, headers, data, contentType,
username, password, allowCache) {
headers = headers || {};
headers["X-ControlView"] = "false";
_httpReq.apply(this, arguments);
};
// register style sheet for backstage separately (important)
store.addNotification("StyleSheetBackstage", refreshStyles);
// option for default privacy setting
config.optionsDesc.chkPrivateMode = "Set your default privacy mode to private";
config.optionsSource.chkPrivateMode = "setting";
config.options.chkPrivateMode = config.options.chkPrivateMode || false;
saveSystemSetting("chkPrivateMode", true);
config.defaultCustomFields["server.workspace"] = plugin.
getCurrentWorkspace(config.options.chkPrivateMode ? "private" : "public");
config.paramifiers.follow = {
onstart: function(v) {
if(!readOnly) {
var bag = "%0_public".format(currentSpace);
story.displayTiddler(null, v, DEFAULT_EDIT_TEMPLATE, null, null,
"server.bag:%0 server.workspace:bags/%0".format(bag));
story.setTiddlerTag(v, "follow", 1);
story.focusTiddler(v, "text");
}
}
};
var fImport = config.macros.fileImport;
if(fImport) {
fImport.uploadTo = "Upload to: ";
var _createForm = config.macros.fileImport.createForm;
config.macros.fileImport.createForm = function(place, wizard, iframeName) {
var container = $("<div />").text(fImport.uploadTo).appendTo(place);
var select = $('<select name="mode" />').appendTo(container)[0];
$('<option value="private" selected>private</a>').appendTo(select);
$('<option value="public">public</a>').appendTo(select);
wizard.setValue("importmode", select);
_createForm.apply(this, [place, wizard, iframeName]);
};
var _onGet = config.macros.importTiddlers.onGetTiddler;
config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
var type = $(wizard.getValue("importmode")).val();
var ws = plugin.getCurrentWorkspace(type);
wizard.setValue("workspace", ws);
_onGet.apply(this, [context, wizard]);
};
}
config.extensions.ServerSideSavingPlugin.reportSuccess = function(msg, tiddler) {
plugin.checkSyncStatus(tiddler);
msg = config.extensions.ServerSideSavingPlugin.locale[msg];
var link = "/" + encodeURIComponent(tiddler.title);
displayMessage(msg.format([tiddler.title]), link);
};
})(jQuery);
//}}}
!SpaceUnplugged
{{unpluggedSpaceTab{
{{wizard{
<<image unsyncedIcon width:48>> Sync is currently unavailable in ~TiddlyWiki due to security constraints in modern browsers. Research is being done to build a suitable alternative. In the meantime if you have changed content in an offline ~TiddlyWiki, you can get your content back into ~TiddlySpace by using the ''import'' functionality from the backstage of the online wiki.
}}}
}}}
!Menu
<<message messages.memberStatus>> <<homeLink>>
{{unsyncedList{<<message messages.syncListHeading>> <<list filter [is[unsynced]]>>}}}
running TiddlySpace@glossary version <<message extensions.tiddlyweb.status.tiddlyspace_version>>
{{autotable{
<<tiddler Backstage##Resources>>
}}}
!Resources
[[blog|@@blog]] [[documentation|@@docs]] [[featured spaces|@@featured]]
!ImportExport
<<fileImport>>
You can download this TiddlySpace as an offline TiddlyWiki:
{{chunkyButton{<<exportSpace>>}}}
!BackstageTiddlers
|upload a <<message messages.privacySetting>> file: <<binaryUpload>>|<<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>>|
|>|<<search>>|
|>|<<tiddler Backstage##Tiddlers>>|
!Tiddlers
<<tabs
txtMainTab
"Recent" "Recently edited tiddlers" TabTimeline
"All" "All tiddlers" TabAll
"Public" "All public tiddlers" [[TiddlySpaceTabs##Public]]
"Private" "All private tiddlers" [[TiddlySpaceTabs##Private]]
"Tags" "All tags" TabTags
"Spaces" "Tiddlers grouped by space" [[TiddlySpaceTabs##Spaces]]
"Missing" "Missing tiddlers" TabMoreMissing
"Orphans" "Orphaned tiddlers" TabMoreOrphans
"Shadows" "Shadowed tiddlers" TabMoreShadowed
>>
!BatchOps
<<tabs
txtPublisherTab
"Private" "Move tiddlers from private to public" Backstage##BatchPrivate
"Public" "Move tiddlers from public to private" Backstage##BatchPublic
>>
!BatchPrivate
<<TiddlySpacePublisher type:private>>
!BatchPublic
<<TiddlySpacePublisher type:public>>
!Plugins
''Note:'' Many of these plugins are core TiddlySpace plugins and cannot be changed unless first cloned.
<<tiddler PluginManager>>
!Tweaks
These options change behavior in TiddlyWiki //only// and may be ineffective in TiddlySpace.
<<tiddler AdvancedOptions>>
/***
|''Name''|TiddlyWebAdaptor|
|''Description''|adaptor for interacting with TiddlyWeb|
|''Author:''|FND|
|''Contributors''|Chris Dent, Martin Budden|
|''Version''|1.4.10|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/adaptors/TiddlyWebAdaptor.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
|''Keywords''|serverSide TiddlyWeb|
!Notes
This plugin includes [[jQuery JSON|http://code.google.com/p/jquery-json/]].
!To Do
* createWorkspace
* document custom/optional context attributes (e.g. filters, query, revision) and tiddler fields (e.g. server.title, origin)
!Code
***/
//{{{
(function($) {
var adaptor = config.adaptors.tiddlyweb = function() {};
adaptor.prototype = new AdaptorBase();
adaptor.serverType = "tiddlyweb";
adaptor.serverLabel = "TiddlyWeb";
adaptor.mimeType = "application/json";
adaptor.parsingErrorMessage = "Error parsing result from server";
adaptor.noBagErrorMessage = "no bag specified for tiddler";
adaptor.locationIDErrorMessage = "no bag or recipe specified for tiddler"; // TODO: rename
// retrieve current status (requires TiddlyWeb status plugin)
adaptor.prototype.getStatus = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/status";
var uri = uriTemplate.format([context.host]);
var req = httpReq("GET", uri, adaptor.getStatusCallback, context,
null, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getStatusCallback = function(status, context, responseText, uri, xhr) {
context.status = responseText ? status : false;
try {
context.statusText = xhr.statusText;
} catch(exc) { // offline (Firefox)
context.status = false;
context.statusText = null;
}
context.httpStatus = xhr.status;
if(context.status) {
context.serverStatus = $.evalJSON(responseText); // XXX: error handling!?
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve a list of workspaces
adaptor.prototype.getWorkspaceList = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.workspaces = [];
var uriTemplate = "%0/recipes"; // XXX: bags?
var uri = uriTemplate.format([context.host]);
var req = httpReq("GET", uri, adaptor.getWorkspaceListCallback,
context, { accept: adaptor.mimeType }, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getWorkspaceListCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
try {
var workspaces = $.evalJSON(responseText);
} catch(ex) {
context.status = false; // XXX: correct?
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
context.workspaces = workspaces.map(function(itm) { return { title: itm }; });
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve a list of tiddlers
adaptor.prototype.getTiddlerList = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/%1/%2/tiddlers%3";
var params = context.filters ? "?" + context.filters : "";
if(context.format) {
params = context.format + params;
}
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), params]);
var req = httpReq("GET", uri, adaptor.getTiddlerListCallback,
context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerListCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
context.tiddlers = [];
try {
var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
} catch(ex) {
context.status = false; // XXX: correct?
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
context.tiddlers.push(tiddler);
}
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// perform global search
adaptor.prototype.getSearchResults = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/search?q=%1%2";
var filterString = context.filters ? ";" + context.filters : "";
var uri = uriTemplate.format([context.host, context.query, filterString]); // XXX: parameters need escaping?
var req = httpReq("GET", uri, adaptor.getSearchResultsCallback,
context, { accept: adaptor.mimeType }, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getSearchResultsCallback = function(status, context, responseText, uri, xhr) {
adaptor.getTiddlerListCallback(status, context, responseText, uri, xhr); // XXX: use apply?
};
// retrieve a particular tiddler's revisions
adaptor.prototype.getTiddlerRevisionList = function(title, limit, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
var req = httpReq("GET", uri, adaptor.getTiddlerRevisionListCallback,
context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerRevisionListCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
context.revisions = [];
try {
var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
} catch(ex) {
context.status = false; // XXX: correct?
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
context.revisions.push(tiddler);
}
var sortField = "server.page.revision";
context.revisions.sort(function(a, b) {
return a.fields[sortField] < b.fields[sortField] ? 1 :
(a.fields[sortField] == b.fields[sortField] ? 0 : -1);
});
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve an individual tiddler revision -- XXX: breaks with standard arguments list -- XXX: convenience function; simply use getTiddler?
adaptor.prototype.getTiddlerRevision = function(title, revision, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.revision = revision;
return this.getTiddler(title, context, userParams, callback);
};
// retrieve an individual tiddler
//# context is an object with members host and workspace
//# callback is passed the new context and userParams
adaptor.prototype.getTiddler = function(title, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = title;
if(context.revision) {
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions/%4";
} else {
uriTemplate = "%0/%1/%2/tiddlers/%3";
}
if(!context.tiddler) {
context.tiddler = new Tiddler(title);
}
context.tiddler.fields["server.type"] = adaptor.serverType;
context.tiddler.fields["server.host"] = AdaptorBase.minHostName(context.host);
context.tiddler.fields["server.workspace"] = context.workspace;
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title),
context.revision]);
var req = httpReq("GET", uri, adaptor.getTiddlerCallback, context,
merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
try {
var tid = $.evalJSON(responseText);
} catch(ex) {
context.status = false;
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
var tiddler = adaptor.toTiddler(tid, context.host);
tiddler.title = context.tiddler.title;
tiddler.fields["server.etag"] = xhr.getResponseHeader("Etag");
// normally we'd assign context.tiddler = tiddler here - but we can't do
// that because of IE, which triggers getTiddler in putTiddlerCallback,
// and since ServerSideSavingPlugin foolishly relies on persistent
// object references, we need to merge the data into the existing object
$.extend(context.tiddler, tiddler);
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve tiddler chronicle (all revisions)
adaptor.prototype.getTiddlerChronicle = function(title, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = title;
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions?fat=1";
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
var req = httpReq("GET", uri, adaptor.getTiddlerChronicleCallback,
context, { accept: adaptor.mimeType }, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
context.responseText = responseText;
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// store an individual tiddler
adaptor.prototype.putTiddler = function(tiddler, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = tiddler.title;
context.tiddler = tiddler;
context.host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var uriTemplate = "%0/%1/%2/tiddlers/%3";
try {
context.workspace = context.workspace || tiddler.fields["server.workspace"];
var workspace = adaptor.resolveWorkspace(context.workspace);
} catch(ex) {
return adaptor.locationIDErrorMessage;
}
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(tiddler.title)]);
var etag = adaptor.generateETag(workspace, tiddler);
var headers = etag ? { "If-Match": etag } : null;
var payload = {
type: tiddler.fields["server.content-type"] || null,
text: tiddler.text,
tags: tiddler.tags,
fields: $.extend({}, tiddler.fields)
};
delete payload.fields.changecount;
$.each(payload.fields, function(key, value) {
if(key.indexOf("server.") == 0) {
delete payload.fields[key];
}
});
payload = $.toJSON(payload);
var req = httpReq("PUT", uri, adaptor.putTiddlerCallback,
context, headers, payload, adaptor.mimeType, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.putTiddlerCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.status) {
var loc = xhr.getResponseHeader("Location");
var etag = xhr.getResponseHeader("Etag");
if(loc && etag) {
var bag = loc.split("/bags/").pop().split("/")[0];
context.tiddler.fields["server.bag"] = bag;
context.tiddler.fields["server.workspace"] = "bags/" + bag;
var rev = etag.split("/").pop().split(/;|:/)[0];
context.tiddler.fields["server.page.revision"] = rev;
context.tiddler.fields["server.etag"] = etag;
if(context.callback) {
context.callback(context, context.userParams);
}
} else { // IE
context.adaptor.getTiddler(context.tiddler.title, context,
context.userParams, context.callback);
}
} else if(context.callback) {
context.callback(context, context.userParams);
}
};
// store a tiddler chronicle
adaptor.prototype.putTiddlerChronicle = function(revisions, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = revisions[0].title;
var headers = null;
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(context.title)]);
if(workspace.type == "bag") { // generate ETag
var etag = [adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(context.title), 0].join("/"); //# zero-revision prevents overwriting existing contents
headers = { "If-Match": '"' + etag + '"' };
}
var payload = $.toJSON(revisions);
var req = httpReq("POST", uri, adaptor.putTiddlerChronicleCallback,
context, headers, payload, adaptor.mimeType, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.putTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.callback) {
context.callback(context, context.userParams);
}
};
// store a collection of tiddlers (import TiddlyWiki HTML store)
adaptor.prototype.putTiddlerStore = function(store, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/%1/%2/tiddlers";
var host = context.host;
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name)]);
var req = httpReq("POST", uri, adaptor.putTiddlerStoreCallback,
context, null, store, "text/x-tiddlywiki", null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.putTiddlerStoreCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.callback) {
context.callback(context, context.userParams);
}
};
// rename an individual tiddler or move it to a different workspace -- TODO: make {from|to}.title optional
//# from and to are objects with members title and workspace (bag; optional),
//# representing source and target tiddler, respectively
adaptor.prototype.moveTiddler = function(from, to, context, userParams, callback) { // XXX: rename parameters (old/new)?
var self = this;
var newTiddler = store.getTiddler(from.title) || store.getTiddler(to.title); //# local rename might already have occurred
var oldTiddler = $.extend(true, {}, newTiddler); //# required for eventual deletion
oldTiddler.title = from.title; //# required for original tiddler's ETag
var _getTiddlerChronicle = function(title, context, userParams, callback) {
return self.getTiddlerChronicle(title, context, userParams, callback);
};
var _putTiddlerChronicle = function(context, userParams) {
if(!context.status) {
return callback(context, userParams);
}
var revisions = $.evalJSON(context.responseText); // XXX: error handling?
// change current title while retaining previous location
for(var i = 0; i < revisions.length; i++) {
delete revisions[i].revision;
if(!revisions[i].fields.origin) { // NB: origin = "<workspace>/<title>"
revisions[i].fields.origin = ["bags", revisions[i].bag, revisions[i].title].join("/");
}
revisions[i].title = to.title;
}
// add new revision
var rev = $.extend({}, revisions[0]);
$.each(newTiddler, function(i, item) {
if(!$.isFunction(item)) {
rev[i] = item;
}
});
rev.title = to.title;
rev.created = rev.created.convertToYYYYMMDDHHMM();
rev.modified = new Date().convertToYYYYMMDDHHMM();
delete rev.fields.changecount;
revisions.unshift(rev);
if(to.workspace) {
context.workspace = to.workspace;
} else if(context.workspace.substring(0, 4) != "bags") { // NB: target workspace must be a bag
context.workspace = "bags/" + rev.bag;
}
var subCallback = function(context, userParams) {
if(!context.status) {
return callback(context, userParams);
}
context.adaptor.getTiddler(newTiddler.title, context, userParams, _deleteTiddler);
};
return self.putTiddlerChronicle(revisions, context, context.userParams, subCallback);
};
var _deleteTiddler = function(context, userParams) {
if(!context.status) {
return callback(context, userParams);
}
$.extend(true, newTiddler, context.tiddler);
context.callback = null;
return self.deleteTiddler(oldTiddler, context, context.userParams, callback);
};
callback = callback || function() {};
context = this.setContext(context, userParams);
context.host = context.host || oldTiddler.fields["server.host"];
context.workspace = from.workspace || oldTiddler.fields["server.workspace"];
return _getTiddlerChronicle(from.title, context, userParams, _putTiddlerChronicle);
};
// delete an individual tiddler
adaptor.prototype.deleteTiddler = function(tiddler, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = tiddler.title; // XXX: not required!?
var uriTemplate = "%0/bags/%1/tiddlers/%2";
var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var bag = tiddler.fields["server.bag"];
if(!bag) {
return adaptor.noBagErrorMessage;
}
var uri = uriTemplate.format([host, adaptor.normalizeTitle(bag),
adaptor.normalizeTitle(tiddler.title)]);
var etag = adaptor.generateETag({ type: "bag", name: bag }, tiddler);
var headers = etag ? { "If-Match": etag } : null;
var req = httpReq("DELETE", uri, adaptor.deleteTiddlerCallback, context, headers,
null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.deleteTiddlerCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.callback) {
context.callback(context, context.userParams);
}
};
// compare two revisions of a tiddler (requires TiddlyWeb differ plugin)
//# if context.rev1 is not specified, the latest revision will be used for comparison
//# if context.rev2 is not specified, the local revision will be sent for comparison
//# context.format is a string as determined by the TiddlyWeb differ plugin
adaptor.prototype.getTiddlerDiff = function(title, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = title;
var tiddler = store.getTiddler(title);
try {
var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
} catch(ex) {
return adaptor.locationIDErrorMessage;
}
var tiddlerRef = [workspace.type + "s", workspace.name, tiddler.title].join("/");
var rev1 = context.rev1 ? [tiddlerRef, context.rev1].join("/") : tiddlerRef;
var rev2 = context.rev2 ? [tiddlerRef, context.rev2].join("/") : null;
var uriTemplate = "%0/diff?rev1=%1";
if(rev2) {
uriTemplate += "&rev2=%2";
}
if(context.format) {
uriTemplate += "&format=%3";
}
var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var uri = uriTemplate.format([host, adaptor.normalizeTitle(rev1),
adaptor.normalizeTitle(rev2), context.format]);
if(rev2) {
var req = httpReq("GET", uri, adaptor.getTiddlerDiffCallback, context, null,
null, null, null, null, true);
} else {
var payload = {
title: tiddler.title,
text: tiddler.text,
modifier: tiddler.modifier,
tags: tiddler.tags,
fields: $.extend({}, tiddler.fields)
}; // XXX: missing attributes!?
payload = $.toJSON(payload);
req = httpReq("POST", uri, adaptor.getTiddlerDiffCallback, context,
null, payload, adaptor.mimeType, null, null, true);
}
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerDiffCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
context.uri = uri;
if(status) {
context.diff = responseText;
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// generate tiddler information
adaptor.prototype.generateTiddlerInfo = function(tiddler) {
var info = {};
var uriTemplate = "%0/%1/%2/tiddlers/%3";
var host = this.host || tiddler.fields["server.host"]; // XXX: this.host obsolete?
host = this.fullHostName(host);
var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
info.uri = uriTemplate.format([host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(tiddler.title)]);
return info;
};
// create Tiddler instance from TiddlyWeb tiddler JSON
adaptor.toTiddler = function(json, host) {
var created = Date.convertFromYYYYMMDDHHMM(json.created);
var modified = Date.convertFromYYYYMMDDHHMM(json.modified);
var fields = json.fields;
fields["server.type"] = adaptor.serverType;
fields["server.host"] = AdaptorBase.minHostName(host);
fields["server.bag"] = json.bag;
fields["server.title"] = json.title;
if(json.recipe) {
fields["server.recipe"] = json.recipe;
}
if(json.type && json.type != "None") {
fields["server.content-type"] = json.type;
}
fields["server.permissions"] = json.permissions.join(", ");
fields["server.page.revision"] = json.revision;
fields["server.workspace"] = "bags/" + json.bag;
var tiddler = new Tiddler(json.title);
tiddler.assign(tiddler.title, json.text, json.modifier, modified, json.tags,
created, json.fields, json.creator);
return tiddler;
};
adaptor.resolveWorkspace = function(workspace) {
var components = workspace.split("/");
return {
type: components[0] == "bags" ? "bag" : "recipe",
name: components[1] || components[0]
};
};
adaptor.generateETag = function(workspace, tiddler) {
var revision = tiddler.fields["server.page.revision"];
var etag = revision == "false" ? null : tiddler.fields["server.etag"];
if(!etag && workspace.type == "bag") {
if(typeof revision == "undefined") {
revision = "0";
} else if(revision == "false") {
return null;
}
etag = [adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(tiddler.title), revision].join("/");
etag = '"' + etag + '"';
}
return etag;
};
adaptor.normalizeTitle = function(title) {
return encodeURIComponent(title);
};
})(jQuery);
/*
* jQuery JSON Plugin
* version: 1.3
* source: http://code.google.com/p/jquery-json/
* license: MIT (http://www.opensource.org/licenses/mit-license.php)
*/
(function($){function toIntegersAtLease(n)
{return n<10?'0'+n:n;}
Date.prototype.toJSON=function(date)
{return this.getUTCFullYear()+'-'+
toIntegersAtLease(this.getUTCMonth())+'-'+
toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.quoteString=function(string)
{if(escapeable.test(string))
{return'"'+string.replace(escapeable,function(a)
{var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};$.toJSON=function(o,compact)
{var type=typeof(o);if(type=="undefined")
return"undefined";else if(type=="number"||type=="boolean")
return o+"";else if(o===null)
return"null";if(type=="string")
{return $.quoteString(o);}
if(type=="object"&&typeof o.toJSON=="function")
return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number")
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));}
if(compact)
return"["+ret.join(",")+"]";else
return"["+ret.join(", ")+"]";}
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
var ret=[];for(var k in o){var name;type=typeof(k);if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;var val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;}
if(compact)
ret.push(name+":"+val);else
ret.push(name+": "+val);}
return"{"+ret.join(", ")+"}";};$.compactJSON=function(o)
{return $.toJSON(o,true);};$.evalJSON=function(src)
{return eval("("+src+")");};$.secureEvalJSON=function(src)
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};})(jQuery);
//}}}
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
//{{{
/* http://keith-wood.name/gChart.html
Google Chart interface for jQuery v1.3.2.
See API details at http://code.google.com/apis/chart/.
Written by Keith Wood (kbwood{at}iinet.com.au) September 2008.
Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
Please attribute the author if you use it. */
/* Request a chart from Google charts.
$('div selector').gchart({type: 'pie', series: [$.gchart.series([101, 84])]});
*/
(function($) { // Hide scope, no $ conflict
/* Google Charting manager. */
function GChart() {
this._defaults = {
width: 0, // Width of the chart
height: 0, // Height of the chart
format: 'png', // Returned format: png, gif
usePost: false, // True to POST instead of GET - for larger charts with more data
margins: null, // The minimum margins (pixels) around the chart:
// all or [left/right, top/bottom] or [left, right, top, bottom]
title: '', // The title of the chart
titleColor: '', // The colour of the title
titleSize: 0, // The font size of the title
opacity: 0, // Make the entire chart semi-transparent (0.0-1.0 or 0-100)
backgroundColor: null, // The background colour for the entire image
chartColor: null, // The background colour for the chart area
legend: '', // The location of the legend: top, topVertical,
// bottom, bottomVertical, left, right, or '' for none
legendOrder: 'normal', // The order of items within a legend: normal, reverse, automatic
legendSize: null, // The minimum size (pixels) of the legend: [width, height]
type: 'pie3D', // Type of chart requested: line, lineXY, sparkline,
// barHoriz, barVert, barHorizGrouped, barVertGrouped, pie, pie3D (default),
// pieConcentric, venn, scatter, radar, radarCurved, map, meter, qrCode, formula
encoding: '', // Type of data encoding: text (default), scaled, simple, extended
series: [this.series('Hello World', [60, 40])], // Details about the values to be plotted
visibleSeries: 0, // The number of series that are directly displayed, 0 for all
dataLabels: [], // Labels for the values across all the series
axes: [], // Definitions for the various axes, each entry is either
// a string of the axis name or a GChartAxis object
ranges: [], // Definitions of ranges for the chart, each entry is an object with
// vertical (boolean), color (string), start (number, 0-1),
// and end (number, 0-1) attributes
markers: [], // Definitions of markers for the chart, each entry is an object with
// shape (arrow, circle, cross, diamond, down, flag, horizontal,
// number, plus, sparkfill, sparkline, square, text, vertical),
// color (string), series (number), item (number), size (number),
// priority (number), text (string), positioned (boolean),
// placement (string or string[]), offsets (number[2])
icons: [], // Definitions of dynamic icons for the chart, each entry is an object with
// name (string), data (string), series (number), item (number), zIndex (number),
// position (number[2]), offsets (number[2])
minValue: 0, // The minimum value of the data, $.gchart.calculate to calculate from data
maxValue: 100, // The maximum value of the data, $.gchart.calculate to calculate from data
gridSize: [], // The x and y spacings between grid lines
gridLine: [], // The line and gap lengths for the grid lines
gridOffsets: [], // The x and y offsets for the grid lines
extension: {}, // Any custom extensions to the Google chart parameters
// Bar charts -------------
barWidth: null, // The width of each bar (pixels) or 'a' for automatic or 'r' for relative
barSpacing: null, // The space (pixels) between bars in a group
barGroupSpacing: null, // The space (pixels) between groups of bars
barZeroPoint: null, // The position (0.0 to 1.0) of the zero-line
// Pie charts -------------
pieOrientation: 0, // The angle (degrees) of orientation from the positive x-axis
// Maps -------------------
mapArea: 'world', // The general area to show: world,
// africa, asia, europe, middle_east, south_america, usa
mapRegions: [], // List of country/state codes to plot
mapDefaultColor: 'bebebe', // The colour for non-plotted countries/states
mapColors: ['blue', 'red'], // The colour range for plotted countries/states
// QR Code ----------------
qrECLevel: null, // Error correction level: low, medium, quarter, high
qrMargin: null, // Margin (squares) around QR code, default is 4
// Callback
onLoad: null, // Function to call when loaded
provideJSON: false // True to return JSON description of chart with the onLoad callback
};
};
/* The name of the data property that holds the instance settings. */
var PROP_NAME = 'gChart';
/* Translations of text colour names into chart values. */
var COLOURS = {aqua: '008080', black: '000000', blue: '0000ff', fuchsia: 'ff00ff', gray: '808080',
green: '008000', grey: '808080', lime: '00ff00', maroon: '800000', navy: '000080',
olive: '808000', orange: 'ffa500', purple: '800080', red: 'ff0000', silver: 'c0c0c0',
teal: '008080', transparent: '00000000', white: 'ffffff', yellow: 'ffff00'};
/* Mapping from plugin chart types to Google chart types. */
var CHART_TYPES = {line: 'lc', lineXY: 'lxy', sparkline: 'ls',
barHoriz: 'bhs', barVert: 'bvs', barHorizGrouped: 'bhg', barVertGrouped: 'bvg', graphviz: 'gv',
pie: 'p', pie3D: 'p3', pieConcentric: 'pc', venn: 'v', scatter: 's',
radar: 'r', radarCurved: 'rs', map: 't', meter: 'gom', qrCode: 'qr', formula: 'tx',
lc: 'lc', lxy: 'lxy', ls: 'ls', bhs: 'bhs', bvs: 'bvs', bhg: 'bhg', bvg: 'bvg', gv: 'gv',
p: 'p', p3: 'p3', pc: 'pc', v: 'v', s: 's',
r: 'r', rs: 'rs', t: 't', gom: 'gom', qr: 'qr', tx: 'tx'};
/* Mapping from plugin shape types to Google chart shapes. */
var SHAPES = {annotation: 'A', arrow: 'a', candlestick: 'F', circle: 'o', cross: 'x',
diamond: 'd', down: 'v', errorbar: 'E', flag: 'f', financial: 'F', horizbar: 'H',
horizontal: 'h', number: 'N', plus: 'c', rectangle: 'C', sparkfill: 'B',
sparkline: 'D', sparkslice: 'b', square: 's', text: 't', vertical: 'V'};
/* Mapping from plugin priority names to chart priority codes. */
var PRIORITIES = {behind: -1, below: -1, normal: 0, above: +1, inFront: +1, '-': -1, '+': +1};
/* Mapping from plugin gradient names to angles. */
var GRADIENTS = {diagonalDown: -45, diagonalUp: 45, horizontal: 0, vertical: 90,
dd: -45, du: 45, h: 0, v: 90};
/* Mapping from plugin alignment names to chart alignment codes. */
var ALIGNMENTS = {left: -1, center: 0, centre: 0, right: +1, l: -1, c: 0, r: +1};
/* Mapping from plugin drawing control names to chart drawing control codes. */
var DRAWING = {line: 'l', ticks: 't', both: 'lt'};
/* Mapping from legend order names to chart drawing control codes. */
var ORDERS = {normal: 'l', reverse: 'r', automatic: 'a', '': '', l: 'l', r: 'r', a: 'a'};
/* Mapping from marker placement names to chart drawing placement codes. */
var PLACEMENTS = {barbase: 's', barcenter: 'c', barcentre: 'c', bartop: 'e', bottom: 'b',
center: 'h', centre: 'h', left: 'l', middle: 'v', right: 'r', top: 't',
b: 'b', c: 'c', e: 'e', h: 'h', l: 'l', r: 'r', s: 's', t: 't', v: 'v'};
/* Characters to use for encoding schemes. */
var SIMPLE_ENCODING = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var EXTENDED_ENCODING = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.';
$.extend(GChart.prototype, {
/* Class name added to elements to indicate already configured with Google charting. */
markerClassName: 'hasGChart',
/* Marker value to indicate min/max calculation from data. */
calculate: -0.123,
/* Possible values for bar width. */
barWidthAuto: 'a', // Automatic resize to fill
barWidthRelative: 'r', // Spacings are relative to bars (0.0 - 1.0)
/* Possible values for number format. */
formatFloat: 'f',
formatPercent: 'p',
formatScientific: 'e',
formatCurrency: 'c',
/* Override the default settings for all Google chart instances.
@param options (object) the new settings to use as defaults */
setDefaults: function(options) {
extendRemove(this._defaults, options || {});
},
/* Create a new data series.
@param label (string, optional) the label for this series
@param data (number[]) the data values for this series
@param colour (string or string[]) the colour(s) for this series
@param fillColour (string, optional) the fill colour for this series or
(object, optional) fill slice with attributes color and range ('start:end') or
(object[], optional) array of above
@param minValue (number, optional with maxValue) the minimum value for this series
@param maxValue (number, optional with minValue) the maximum value for this series
@param thickness (number) the thickness (pixels) of the line for this series
@param segments (number[2]) the line and gap lengths (pixels) for this series
@return (object) the new series object */
series: function(label, data, colour, fillColour, minValue, maxValue, thickness, segments) {
if ($.isArray(label)) { // Optional label
segments = thickness;
thickness = maxValue;
maxValue = minValue;
minValue = fillColour;
fillColour = colour;
colour = data;
data = label;
label = '';
}
if (typeof colour == 'number') { // Optional colour/fillColour
segments = maxValue;
thickness = minValue;
maxValue = fillColour;
minValue = colour;
fillColour = null;
colour = null;
}
if (typeof fillColour == 'number') { // Optional fillColour
segments = thickness;
thickness = maxValue;
maxValue = minValue;
minValue = fillColour;
fillColour = null;
}
if ($.isArray(maxValue)) { // Optional min/max values
segments = maxValue;
thickness = minValue;
maxValue = null;
minValue = null;
}
return {label: label, data: data || [], color: colour || '',
fillColor: fillColour, minValue: minValue, maxValue: maxValue,
lineThickness: thickness, lineSegments: segments};
},
/* Load series data from CSV.
Include a header row if fields other than data required.
Use these names - label, color, fillColor, minValue, maxValue,
lineThickness, lineSegmentLine, lineSegmentGap - for series attributes.
Data columns should be labelled ynn, where nn is a sequential number.
For X-Y line charts, include xnn columns before corresponding ynn.
@param csv (string or string[]) the series data in CSV format
@return (object[]) the series definitions */
seriesFromCsv: function(csv) {
var seriesData = [];
if (!$.isArray(csv)) {
csv = csv.split('\n');
}
if (!csv.length) {
return seriesData;
}
var xyData = false;
var sColumns = [];
var xColumns = [];
var fields = ['label', 'color', 'fillColor', 'minValue', 'maxValue',
'lineThickness', 'lineSegmentLine', 'lineSegmentGap'];
$.each(csv, function(i, line) {
var cols = line.split(',');
if (i == 0 && isNaN(parseFloat(cols[0]))) { // Header row
$.each(cols, function(i, val) {
if ($.inArray(val, fields) > -1) { // Note the positions of the columns
sColumns[i] = val;
}
else if (val.match(/^x\d+$/)) { // Column with x-coordinate
xColumns[i] = val;
}
});
}
else {
var series = {};
var data = [];
var saveX = null;
$.each(cols, function(i, val) {
if (sColumns[i]) { // Non-data value
var pos = $.inArray(sColumns[i], fields);
series[sColumns[i]] = (pos > 2 ? $.gchart._numeric(val, 0) : val);
}
else if (xColumns[i]) { // X-coordinate
saveX = (val ? $.gchart._numeric(val, -1) : null);
xyData = true;
}
else {
var y = $.gchart._numeric(val, -1);
data.push(saveX != null ? [saveX, y] : y);
saveX = null;
}
});
if (series.lineSegmentLine != null && series.lineSegmentGap != null) {
series.lineSegments = [series.lineSegmentLine, series.lineSegmentGap];
series.lineSegmentLine = series.lineSegmentGap = null;
}
seriesData.push($.extend(series, {data: data}));
}
});
return (xyData ? this.seriesForXYLines(seriesData) : seriesData);
},
/* Load series data from XML. All attributes are optional except point/@y.
<data>
<series label="" color="" fillColor="" minValue="" maxValue="" lineThickness="" lineSegments="">
<point x="" y=""/>
...
</series>
...
</data>
@param xml (string or Document) the XML containing the series data
@return (object[]) the series definitions */
seriesFromXml: function(xml) {
if ($.browser.msie && typeof xml == 'string') {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.validateOnParse = false;
doc.resolveExternals = false;
doc.loadXML(xml);
xml = doc;
}
xml = $(xml);
var seriesData = [];
var xyData = false;
try {
xml.find('series').each(function() {
var series = $(this);
var data = [];
series.find('point').each(function() {
var point = $(this);
var x = point.attr('x');
if (x != null) {
xyData = true;
x = $.gchart._numeric(x, -1);
}
y = $.gchart._numeric(point.attr('y'), -1);
data.push(x ? [x, y] : y);
});
var segments = series.attr('lineSegments');
if (segments) {
segments = segments.split(',');
for (var i = 0; i < segments.length; i++) {
segments[i] = $.gchart._numeric(segments[i], 1);
}
}
seriesData.push({label: series.attr('label'), data: data,
color: series.attr('color'), fillColor: series.attr('fillColor'),
minValue: $.gchart._numeric(series.attr('minValue'), null),
maxValue: $.gchart._numeric(series.attr('maxValue'), null),
lineThickness: $.gchart._numeric(series.attr('lineThickness'), null),
lineSegments: segments});
});
}
catch (e) {
// Ignore
}
return (xyData ? this.seriesForXYLines(seriesData) : seriesData);
},
/* Force a value to be numeric.
@param val (string) the value to convert
@param whenNaN (number) value to use if not numeric
@return (number) the numeric equivalent or whenNaN if not numeric */
_numeric: function(val, whenNaN) {
val = parseFloat(val);
return (isNaN(val) ? whenNaN : val);
},
/* Prepare series for a line XY chart.
@param series (object[]) the details of the points to plot,
each data value may be an array of two points
@return (object[]) the transformed series
@deprecated in favour of seriesForXYLines */
lineXYSeries: function(series) {
return this.seriesForXYLines(series);
},
/* Prepare series for a line XY chart.
@param series (object[]) the details of the points to plot,
each data value may be an array of two points
@return (object[]) the transformed series */
seriesForXYLines: function(series) {
var xySeries = [];
for (var i = 0; i < series.length; i++) {
var xNull = !$.isArray(series[i].data[0]);
var xData = (xNull ? [null] : []);
var yData = [];
for (var j = 0; j < series[i].data.length; j++) {
if (xNull) {
yData.push(series[i].data[j]);
}
else {
xData.push(series[i].data[j][0]);
yData.push(series[i].data[j][1]);
}
}
xySeries.push($.gchart.series(series[i].label, xData, series[i].color,
series[i].fillColor, series[i].minValue, series[i].maxValue,
series[i].lineThickness, series[i].lineSegments));
xySeries.push($.gchart.series('', yData, '',
series[i].fillColor, series[i].minValue, series[i].maxValue,
series[i].lineThickness, series[i].lineSegments));
}
return xySeries;
},
/* Prepare options for a scatter chart.
@param values (number[][]) the coordinates of the points:
[0] is the x-coord, [1] is the y-coord, [2] is the percentage size
@param labels (string[]) the labels for the groups (optional)
@param colours (string[]) the colours for the labels (optional)
@param options (object) additional settings (optional)
@return (object) the configured options object */
scatter: function(values, labels, colours, options) {
if (!$.isArray(labels)) {
options = labels;
colours = null;
labels = null;
}
var series = [[], [], []];
for (var i = 0; i < values.length; i++) {
series[0][i] = values[i][0];
series[1][i] = values[i][1];
series[2][i] = values[i][2] || 100;
}
options = options || {};
if (labels) {
options.extension = {chdl: labels.join('|')};
}
if (colours) {
colours = $.map(colours, function(v, i) {
return $.gchart.color(v);
});
$.extend(options.extension, {chco: colours.join('|')});
}
return $.extend({}, options,
{type: 'scatter', series: [$.gchart.series(series[0]),
$.gchart.series(series[1]), $.gchart.series(series[2])]});
},
/* Prepare options for a Venn diagram.
@param size1 (number) the relative size of the first circle
@param size2 (number) the relative size of the second circle
@param size3 (number) the relative size of the third circle
@param overlap12 (number) the overlap between circles 1 and 2
@param overlap13 (number) the overlap between circles 1 and 3
@param overlap23 (number) the overlap between circles 2 and 3
@param overlap123 (number) the overlap between all circles
@param options (object) additional settings (optional)
@return (object) the configured options object */
venn: function(size1, size2, size3, overlap12, overlap13, overlap23, overlap123, options) {
return $.extend({}, options || {}, {type: 'venn', series:
[$.gchart.series([size1, size2, size3, overlap12, overlap13, overlap23, overlap123])]});
},
/* Prepare options for a Google meter.
@param text (string or string[]) the text to show on the arrow (optional)
@param values (number or number[] or [] of these) the position(s) of the arrow(s)
@param maxValue (number) the maximum value for the meter (optional, default 100)
@param colours (string[]) the colours to use for the band (optional)
@param labels (string[]) labels appearing beneath the meter (optional)
@param styles (number[][4]) the styles of each series' arrows:
width, dash, space, arrow size (optional)
@param options (object) additional settings (optional)
@return (object) the configured options object */
meter: function(text, values, maxValue, colours, labels, styles, options) {
if (typeof text != 'string' && !$.isArray(text)) {
options = styles;
styles = labels;
labels = colours;
colours = maxValue;
maxValue = values;
values = text;
text = '';
}
if (typeof maxValue != 'number') {
options = styles;
styles = labels;
labels = colours;
colours = maxValue;
maxValue = null;
}
if (!$.isArray(colours)) {
options = styles;
styles = labels;
labels = colours;
colours = null;
}
if (!$.isArray(labels)) {
options = styles;
styles = labels;
labels = null;
}
if (!$.isArray(styles)) {
options = styles;
styles = null;
}
values = ($.isArray(values) ? values : [values]);
var multi = false;
for (var i = 0; i < values.length; i++) {
multi = multi || $.isArray(values[i]);
}
var ss = (multi ? [] : [$.gchart.series(values)]);
if (multi) {
for (var i = 0; i < values.length; i++) {
ss.push($.gchart.series($.isArray(values[i]) ? values[i] : [values[i]]));
}
}
values = ss;
if (colours) {
var cs = '';
$.each(colours, function(i, v) {
cs += ',' + $.gchart.color(v);
});
colours = cs.substr(1);
}
if (styles) {
var ls = ['', ''];
$.each(styles, function(i, v) {
v = ($.isArray(v) ? v : [v]);
ls[0] += '|' + $.gchart.color(v.slice(0, 3).join(','));
ls[1] += '|' + (v[3] || 15);
});
styles = ls[0].substr(1) + ls[1];
}
var axis = (labels && labels.length ? $.gchart.axis('y', labels) : null);
return $.extend({}, options || {}, {type: 'meter',
maxValue: maxValue || 100, series: values,
dataLabels: ($.isArray(text) ? text : [text || ''])},
(colours ? {extension: {chco: colours}} : {}),
(axis ? {axes: [axis]} : {}),
(styles ? {extension: {chls: styles}} : {}));
},
/* Prepare options for a map chart.
@param mapArea (string) the region of the world to show (optional)
@param values (object) the countries/states to plot -
attributes are country/state codes and values
@param defaultColour (string) the colour for regions without values (optional)
@param colour (string or string[]) the starting colour or
gradient colours for rendering values (optional)
@param endColour (string) the ending colour for rendering values (optional)
@param options (object) additional settings (optional)
@return (object) the configured options object */
map: function(mapArea, values, defaultColour, colour, endColour, options) {
if (typeof mapArea == 'object') { // Optional mapArea
options = endColour;
endColour = colour;
colour = defaultColour;
defaultColour = values;
values = mapArea;
mapArea = 'world';
}
if (typeof defaultColour == 'object') {
options = defaultColour;
endColour = null;
colour = null;
defaultColour = null;
}
else if (typeof colour == 'object' && !$.isArray(colour)) {
options = colour;
endColour = null;
colour = null;
}
else if (typeof endColour == 'object') {
options = endColour;
endColour = null;
}
var mapRegions = [];
var data = [];
var i = 0;
for (var name in values) {
mapRegions[i] = name;
data[i] = values[name];
i++;
}
return $.extend({}, options || {}, {type: 'map',
mapArea: mapArea, mapRegions: mapRegions,
mapDefaultColor: defaultColour || $.gchart._defaults.mapDefaultColor,
mapColors: ($.isArray(colour) ? colour : [colour || $.gchart._defaults.mapColors[0],
endColour || $.gchart._defaults.mapColors[1]]),
series: [$.gchart.series('', data)]});
},
/* Prepare options for generating a QR Code.
@param text (object) the QR code settings or
(string) the text to encode
@param encoding (string) the encoding scheme (optional)
@param ecLevel (string) the error correction level: l, m, q, h (optional)
@param margin (number) the margin around the code (optional)
@return (object) the configured options object */
qrCode: function(text, encoding, ecLevel, margin) {
var options = {};
if (typeof text == 'object') {
options = text;
}
else { // Individual fields
options = {dataLabels: [text], encoding: encoding,
qrECLevel: ecLevel, qrMargin: margin};
}
options.type = 'qrCode';
if (options.text) {
options.dataLabels = [options.text];
options.text = null;
}
return options;
},
/* Prepare options for a GraphViz chart.
@param engine (string, optional) the graphing engine to use:
dot (default), neato, twopi, circo, fdp
@param options (object, optional) other options for the chart
@param graph (string) the DOT representation of the nodes to graph
@return (object) the configured options object */
graphviz: function(engine, options, graph) {
if (arguments.length == 1) {
graph = engine;
engine = 'dot';
}
if (options && typeof options != 'object') {
graph = options;
options = {};
}
options = options || {};
options.type = 'gv' + (engine != 'dot' ? ':' + engine : '');
options.dataLabels = [graph];
return options;
},
/* Generate a Google chart color.
@param r (string) colour name or '#hhhhhh' or
(number) red value (0-255)
@param g (number) green value (0-255) or
(number) alpha value (0-255, optional) if r is name
@param b (number) blue value (0-255)
@param a (number) alpha value (0-255, optional)
@return (string) the translated colour */
color: function(r, g, b, a) {
var checkRange = function(value) {
if (typeof value == 'number' && (value < 0 || value > 255)) {
throw 'Value out of range (0-255) ' + value;
}
};
var twoDigits = function(value) {
return (value.length == 1 ? '0' : '') + value;
};
if (typeof r == 'string') {
checkRange(g);
return (r.match(/^#([A-Fa-f0-9]{2}){3,4}$/) ? r.substring(1) :
(COLOURS[r] || r) + (g ? twoDigits(g.toString(16)) : ''));
}
checkRange(r);
checkRange(g);
checkRange(b);
checkRange(a);
return twoDigits(r.toString(16)) + twoDigits(g.toString(16)) +
twoDigits(b.toString(16)) + (a ? twoDigits(a.toString(16)) : '');
},
/* Create a simple linear gradient definition for a background.
@param angle (string or number) the angle of the gradient from positive x-axis
@param colour1 (string[]) an array of colours or
(string) the starting colour
@param colour2 (string, optional) the ending colour
@return (object) the gradient definition */
gradient: function(angle, colour1, colour2) {
var colourPoints = [];
if ($.isArray(colour1)) {
var step = 1 / (colour1.length - 1);
for (var i = 0; i < colour1.length; i++) {
colourPoints.push([colour1[i], Math.round(i * step * 100) / 100]);
}
}
else {
colourPoints = [[colour1, 0], [colour2, 1]];
}
return {angle: angle, colorPoints: colourPoints};
},
/* Create a colour striping definition for a background.
@param angle (string or number) the angle of the stripes from positive x-axis
@param colours (string[]) the colours to stripe
@return (object) the stripe definition */
stripe: function(angle, colours) {
var colourPoints = [];
var width = Math.round(100 / colours.length) / 100;
for (var i = 0; i < colours.length; i++) {
colourPoints.push([colours[i], width]);
}
return {angle: angle, striped: true, colorPoints: colourPoints};
},
/* Create a range definition.
@param vertical (boolean, optional) true if vertical, false if horizontal
@param colour (string) the marker's colour
@param start (number) the starting point for the range (0.0 to 1.0)
@param end (number, optional) the ending point for the range (0.0 to 1.0)
@return (object) the range definition */
range: function(vertical, colour, start, end) {
if (typeof vertical == 'string') { // Optional vertical
end = start;
start = colour;
colour = vertical;
vertical = false;
}
return {vertical: vertical, color: colour, start: start, end: end};
},
/* Create a marker definition.
@param shape (string) the marker shape
@param colour (string) the marker's colour
@param series (number) the series to which the marker applies
@param item (number or string or number[2 or 3], optional)
the item in the series to which it applies or 'all' or
'everyn' or 'everyn[s:e]' or [start, end, every]
@param size (number, optional) the size (pixels) of the marker or
(string) 'thickness:length' for horizline or vertical
@param priority (string or number, optional) the rendering priority
@param text (string, optional) the display text for a text type marker
@param positioned (boolean, optional) true to absolutely position the marker
@param placement (string or string[], optional) placement locations
@param offsets (number[2], optional) pixel offsets, horizontal and vertical
@return (object) the marker definition */
marker: function(shape, colour, series, item, size, priority, text,
positioned, placement, offsets) {
if (typeof size == 'boolean') {
offsets = text;
placement = priority;
positioned = size;
text = null;
priority = null;
size = null;
}
if ($.isArray(size)) {
if (typeof size[0] == 'string') {
offsets = priority;
placement = size;
}
else {
offsets = size;
placement = null;
}
positioned = null;
text = null;
priority = null;
size = null;
}
if (typeof priority == 'boolean') {
offsets = positioned;
placement = text;
positioned = priority;
text = null;
priority = null;
}
if ($.isArray(priority)) {
if (typeof priority[0] == 'string') {
offsets = text;
placement = priority;
}
else {
offsets = priority;
placement = null;
}
positioned = null;
text = null;
priority = null;
}
if (typeof text == 'boolean') {
offsets = placement;
placement = positioned;
positioned = text;
text = null;
}
if ($.isArray(text)) {
if (typeof text[0] == 'string') {
offsets = positioned;
placement = text;
}
else {
offsets = text;
placement = null;
}
positioned = null;
text = null;
}
if ($.isArray(positioned)) {
if (typeof positioned[0] == 'string') {
offsets = placement;
placement = positioned;
}
else {
offsets = positioned;
placement = null;
}
positioned = null;
}
if ($.isArray(placement) && typeof placement[0] != 'string') {
offsets = placement;
placement = null;
}
return {shape: shape, color: colour, series: series,
item: (item || item == 0 ? item : -1), size: size || 10,
priority: (priority != null ? priority : 0), text: text,
positioned: positioned, placement: placement, offsets: offsets};
},
/* Create a dynamic icon definition.
@param name (string) the name of the icon to use
@param data (string) the icon's encoded parameters
@param series (number, optional) the series to which the icon applies
@param item (number or string or number[2 or 3], optional)
the item in the series to which it applies or 'all' (default)
or 'everyn' or [start, end, every]
@param zIndex (number, optional) the z-index (-1.0 to 1.0)
@param position (number[2], optional) an absolute chart position (0.0 to 1.0)
@param offsets (number[2], optional) pixel offsets
@return (object) the icon definition */
icon: function(name, data, series, item, zIndex, position, offsets) {
if ($.isArray(series)) {
offsets = item;
position = series;
zIndex = null;
item = null;
series = null;
}
if ($.isArray(zIndex)) {
offsets = position;
position = zIndex;
zIndex = null;
}
return {name: name, data: data, series: series || 0, item: (item || item == 0 ? item : 'all'),
zIndex: zIndex, position: position, offsets: offsets};
},
/* Create a number format for a marker.
@param type (object) containing all these settings or
(string) 'f' for floating point, 'p' for percentage,
'e' for scientific notation, 'c<CUR>' for currency (as specified by CUR)
@param prefix (string, optional) text appearing before the number
@param suffix (string, optional - can only be present if prefix is present)
text appearing after the number
@param precision (number, optional) the number of decimal places
@param showX (boolean, optional) true to show the x-value, false for the y-value
@param zeroes (boolean, optional - can only be present if showX is present)
true to display trailing zeroes
@param separators (boolean, optional - can only be present if showX and zeroes are present)
true to display group separators
@return (string) the format definition */
numberFormat: function(type, prefix, suffix, precision, showX, zeroes, separators) {
var format = initNumberFormat(type, prefix, suffix, precision, showX, zeroes, separators);
return format.prefix + '*' + format.type + format.precision + (format.zeroes ? 'z' : '') +
(format.separators ? 's' : '') + (format.showX ? 'x' : '') + '*' + format.suffix;
},
/* Create an axis definition.
@param axis (string) the axis position: top, bottom, left, right
@param labels (string[]) the labels for this axis
@param positions (number[], optional) the positions of the labels
@param rangeStart (number, optional with next two) start of range
@param rangeEnd (number, optional with above) end of range
@param rangeInterval (number, optional with above) interval between values in the range
@param colour (string, optional) the axis colour
@param alignment (string, optional) the labels' alignment
@param size (number, optional) the labels' size
@param format (object, optional) the labels' number format options
@return (object) the axis definition */
axis: function(axis, labels, positions, rangeStart,
rangeEnd, rangeInterval, colour, alignment, size, format) {
return new GChartAxis(axis, labels, positions, rangeStart,
rangeEnd, rangeInterval, colour, alignment, size, format);
},
/* Determine the region within a chart.
@param event (MouseEvent) the mouse event contining the cursor position
@param jsonData (object) the JSON description of the chart
@return (object) the current region details (type, series, and point) or null if none */
findRegion: function(event, jsonData) {
if (!jsonData || !jsonData.chartshape) {
return null;
}
var decodeName = function(name) {
var matches = name.match(/([^\d]+)(\d+)(?:_(\d)+)?/);
return {type: matches[1], series: parseInt(matches[2]), point: parseInt(matches[3] || -1)};
};
var offset = $(event.target).offset();
var x = event.pageX - offset.left;
var y = event.pageY - offset.top;
for (var i = 0; i < jsonData.chartshape.length; i++) {
var shape = jsonData.chartshape[i];
switch (shape.type) {
case 'RECT':
if (shape.coords[0] <= x && x <= shape.coords[2] &&
shape.coords[1] <= y && y <= shape.coords[3]) {
return decodeName(shape.name);
}
break;
case 'CIRCLE':
if (Math.abs(x - shape.coords[0]) <= shape.coords[2] &&
Math.abs(y - shape.coords[1]) <= shape.coords[2] &&
Math.sqrt(Math.pow(x - shape.coords[0], 2) +
Math.pow(y - shape.coords[1], 2)) <= shape.coords[2]) {
return decodeName(shape.name);
}
break;
case 'POLY':
if ($.gchart._insidePolygon(shape.coords, x, y)) {
return decodeName(shape.name);
}
break;
}
}
return null;
},
/* Determine whether a point is within a polygon.
Ray casting algorithm adapted from http://ozviz.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/.
@param coords (number[]) the polygon coords as [x1, y1, x2, y2, ...]
@param x (number) the point's x-coord
@param y (number) the point's y-coord
@return (boolean) true if the point is inside, false if not */
_insidePolygon: function(coords, x, y) {
var counter = 0;
var p1 = [coords[0], coords[1]];
for (var i = 2; i <= coords.length; i += 2) {
var p2 = [coords[i % coords.length], coords[i % coords.length + 1]];
if (y > Math.min(p1[1], p2[1]) && y <= Math.max(p1[1], p2[1])) {
if (x <= Math.max(p1[0], p2[0]) && p1[1] != p2[1]) {
var xinters = (y - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0];
if (p1[0] == p2[0] || x <= xinters) {
counter++;
}
}
}
p1 = p2;
}
return (counter % 2 != 0);
},
/* Attach the Google chart functionality to a div.
@param target (element) the containing division
@param options (object) the settings for this Google chart instance (optional) */
_attachGChart: function(target, options) {
target = $(target);
if (target.is('.' + this.markerClassName)) {
return;
}
target.addClass(this.markerClassName);
options = options || {};
var width = options.width || parseInt(target.css('width'), 10);
var height = options.height || parseInt(target.css('height'), 10);
var allOptions = $.extend({}, this._defaults, options,
{width: width, height: height});
$.data(target[0], PROP_NAME, allOptions);
this._updateChart(target[0], allOptions);
},
/* Reconfigure the settings for a Google charting div.
@param target (element) the containing division
@param name (object) the new settings for this Google chart instance or
(string) the name of a single option
@param value (any, optional) the option's value */
_changeGChart: function(target, name, value) {
var options = name || {};
if (typeof name == 'string') {
options = {};
options[name] = value;
}
var curOptions = $.data(target, PROP_NAME);
extendRemove(curOptions || {}, options);
$.data(target, PROP_NAME, curOptions);
this._updateChart(target, curOptions);
},
/* Remove the Google charting functionality from a div.
@param target (element) the containing division */
_destroyGChart: function(target) {
target = $(target);
if (!target.is('.' + this.markerClassName)) {
return;
}
target.removeClass(this.markerClassName).empty();
$.removeData(target[0], PROP_NAME);
},
/* Generate the Google charting request with the new settings.
@param options (object) the new settings for this Google chart instance
@return (string) the Google chart URL */
_generateChart: function(options) {
var type = (options.type && options.type.match(/.+:.+/) ?
options.type : CHART_TYPES[options.type] || 'p3');
var encoding = this['_' + options.encoding + 'Encoding'] ||
this['_textEncoding'];
var labels = '';
for (var i = 0; i < options.dataLabels.length; i++) {
labels += '|' + encodeURIComponent(options.dataLabels[i] || '');
}
labels = (labels.length == options.dataLabels.length ? '' : labels);
var legends = '';
var colours = '';
var hasColour = false;
var lines = '';
for (var i = 0; i < options.series.length; i++) {
var clrs = '';
if (type != 'lxy' || i % 2 == 0) {
legends += '|' + encodeURIComponent(options.series[i].label || '');
var sep = ',';
$.each(($.isArray(options.series[i].color) ? options.series[i].color :
[options.series[i].color]), function(i, v) {
var colour = $.gchart.color(v || '');
if (colour) {
hasColour = true;
}
clrs += sep + (colour || '000000');
sep = '|';
});
}
colours += (hasColour ? clrs : '');
if (type.substr(0, 1) == 'l' && options.series[i].lineThickness &&
$.isArray(options.series[i].lineSegments)) {
lines += '|' + options.series[i].lineThickness + ',' +
options.series[i].lineSegments.join(',');
}
}
var include = function(name, value) {
return (value ? name + value : '');
};
var addSize = function() {
options.width = Math.max(10, Math.min(options.width, 1000));
options.height = Math.max(10, Math.min(options.height, 1000));
if (type != 't' && options.width * options.height > 300000) {
options.height = Math.floor(300000 / options.width);
}
return (type != 't' ? '&chs=' + options.width + 'x' + options.height :
'&chs=' + Math.min(440, options.width) + 'x' + Math.min(220, options.height));
};
var addMargins = function() {
var margins = options.margins;
margins = (margins == null ? null :
(typeof margins == 'number' ? [margins, margins, margins, margins] :
(!$.isArray(margins) ? null :
(margins.length == 4 ? margins :
(margins.length == 2 ? [margins[0], margins[0], margins[1], margins[1]] : null)))));
return (!margins ? '' : '&chma=' + margins.join(',') +
(!options.legendSize || options.legendSize.length != 2 ? '' :
'|' + options.legendSize.join(',')));
};
var qrOptions = function() {
return include('&choe=', options.encoding) +
(options.qrECLevel || options.qrMargin ?
'&chld=' + (options.qrECLevel ? options.qrECLevel.charAt(0) : 'l') +
(options.qrMargin != null ? '|' + options.qrMargin : '') : '') +
(labels ? '&chl=' + labels.substr(1) : '');
};
var noDataOptions = function() {
return '&chl=' + labels.substr(1);
};
var mapOptions = function() {
var colours = '';
for (var i = 0; i < options.mapColors.length; i++) {
colours += ',' + $.gchart.color(options.mapColors[i]);
}
return '&chtm=' + (options.mapArea || 'world') +
'&chd=' + encoding.apply($.gchart, [options]) +
(options.mapRegions && options.mapRegions.length ?
'&chld=' + options.mapRegions.join('') : '') +
'&chco=' + $.gchart.color(options.mapDefaultColor) + colours;
};
var pieOptions = function() {
return (options.pieOrientation ?
'&chp=' + (options.pieOrientation / 180 * Math.PI) : '') +
standardOptions();
};
var standardOptions = function() {
return '&chd=' + encoding.apply($.gchart, [options]) +
(labels ? '&chl=' + labels.substr(1) : '');
};
var addBarSizings = function() {
return (type.substr(0, 1) != 'b' ? '' : (options.barWidth == null ? '' :
'&chbh=' + options.barWidth +
(options.barSpacing == null ? '' : ',' + (options.barWidth == $.gchart.barWidthRelative ?
Math.min(Math.max(options.barSpacing, 0.0), 1.0) : options.barSpacing) +
(options.barGroupSpacing == null ? '' : ',' + (options.barWidth == $.gchart.barWidthRelative ?
Math.min(Math.max(options.barGroupSpacing, 0.0), 1.0) : options.barGroupSpacing)))) +
(options.barZeroPoint == null ? '' : '&chp=' + options.barZeroPoint));
};
var addLineStyles = function() {
return (type.charAt(0) == 'l' && lines ? '&chls=' + lines.substr(1) : '');
};
var addColours = function() {
return (colours.length > options.series.length ? '&chco=' + colours.substr(1) : '');
};
var addTitle = function() {
return include('&chtt=', encodeURIComponent(options.title)) +
(options.titleColor || options.titleSize ?
'&chts=' + ($.gchart.color(options.titleColor) || '000000') + ',' +
(options.titleSize || 20) : '');
};
var addBackground = function(area, background) {
if (background == null) {
return '';
}
if (typeof background == 'string') {
return area + ',s,' + $.gchart.color(background);
}
var bg = area + ',l' + (background.striped ? 's' : 'g') + ',' +
(GRADIENTS[background.angle] != null ?
GRADIENTS[background.angle] : background.angle);
for (var i = 0; i < background.colorPoints.length; i++) {
bg += ',' + $.gchart.color(background.colorPoints[i][0]) +
',' + background.colorPoints[i][1];
}
return bg;
};
var addBackgrounds = function() {
var opacity = (!options.opacity ? null : '000000' +
Math.floor(options.opacity / (options.opacity > 1 ? 100 : 1) * 255).toString(16));
if (opacity && opacity.length < 8) {
opacity = '0' + opacity;
}
var backgrounds = addBackground('|a', opacity) +
addBackground('|bg', options.backgroundColor) +
addBackground('|c', options.chartColor);
return (backgrounds ? '&chf=' + backgrounds.substr(1) : '');
};
var addGrids = function() {
return (options.gridSize.length == 0 ? '' :
'&chg=' + options.gridSize[0] + ',' + options.gridSize[1] +
(options.gridLine.length == 0 ? '' :
',' + options.gridLine[0] + ',' + options.gridLine[1] +
(options.gridOffsets.length == 0 ? '' :
',' + options.gridOffsets[0] + ',' + options.gridOffsets[1])));
};
var addLegends = function() {
var order = (options.legendOrder && options.legendOrder.match(/^\d+(,\d+)*$/) ?
options.legendOrder : ORDERS[options.legendOrder]) || '';
return (!options.legend ||
(type != 'lxy' && legends.length <= options.series.length) ||
(type == 'lxy' && legends.length <= (options.series.length / 2)) ? '' :
'&chdl=' + legends.substr(1) + include('&chdlp=',
options.legend.charAt(0) + (options.legend.indexOf('V') > -1 ? 'v' : '') +
include('|', order)));
};
var addExtensions = function() {
var params = '';
for (var name in options.extension) {
params += '&' + name + '=' + options.extension[name];
}
return params;
};
var format = options.format || 'png';
return 'http://chart.apis.google.com/chart?' +
(format != 'png' ? 'chof=' + format + '&' : '') +
'cht=' + type + addSize() + addMargins() +
(type == 'qr' ? qrOptions() : (type.match(/tx|gv(:\w+)?/) ? noDataOptions() :
(type == 't' ? mapOptions() : (type.charAt(0) == 'p' ? pieOptions() : standardOptions())))) +
addBarSizings() + addLineStyles() + addColours() + addTitle() +
this._addAxes(options) + addBackgrounds() + addGrids() +
this._addMarkers(options) + this._addIcons(options) + addLegends() + addExtensions();
},
/* Generate axes parameters.
@param options (object) the current instance settings
@return (string) the axes parameters */
_addAxes: function(options) {
var axes = '';
var axesLabels = '';
var axesPositions = '';
var axesRanges = '';
var axesStyles = '';
var axesTicks = '';
for (var i = 0; i < options.axes.length; i++) {
var axisDef = (typeof options.axes[i] == 'string' ?
new GChartAxis(options.axes[i]) : options.axes[i]);
var axis = axisDef.axis().charAt(0);
axes += ',' + (axis == 'b' ? 'x' : (axis == 'l' ? 'y' : axis));
if (axisDef.labels()) {
var labels = '';
for (var j = 0; j < axisDef.labels().length; j++) {
labels += '|' + encodeURIComponent(axisDef.labels()[j] || '');
}
axesLabels += (labels ? '|' + i + ':' + labels : '');
}
if (axisDef.positions()) {
var positions = '';
for (var j = 0; j < axisDef.positions().length; j++) {
positions += ',' + axisDef.positions()[j];
}
axesPositions += (positions ? '|' + i + positions : '');
}
if (axisDef.range()) {
var range = axisDef.range();
axesRanges += '|' + i + ',' + range[0] + ',' + range[1] +
(range[2] ? ',' + range[2] : '');
}
if (axisDef.style() || axisDef.drawing() || axisDef.ticks() || axisDef.format()) {
var style = axisDef.style() || {};
var ticks = axisDef.ticks() || {};
axesStyles += '|' + i +
(axisDef.format() ? 'N' + this.numberFormat(axisDef.format()) : '') + ',' +
$.gchart.color(style.color || 'gray') + ',' +
(style.size || 10) + ',' +
(ALIGNMENTS[style.alignment] || style.alignment || 0) +
(!axisDef.drawing() && !ticks.color ? '' : ',' +
(DRAWING[axisDef.drawing()] || axisDef.drawing() || 'lt') +
(ticks.color ? ',' + $.gchart.color(ticks.color) : ''));
}
if (axisDef.ticks() && axisDef.ticks().length) {
axesTicks += '|' + i + ',' + axisDef.ticks().length;
}
}
return (!axes ? '' : '&chxt=' + axes.substr(1) +
(!axesLabels ? '' : '&chxl=' + axesLabels.substr(1)) +
(!axesPositions ? '' : '&chxp=' + axesPositions.substr(1)) +
(!axesRanges ? '' : '&chxr=' + axesRanges.substr(1)) +
(!axesStyles ? '' : '&chxs=' + axesStyles.substr(1)) +
(!axesTicks ? '' : '&chxtc=' + axesTicks.substr(1)));
},
/* Generate markers parameters.
@param options (object) the current instance settings
@return (string) the markers parameters */
_addMarkers: function(options) {
var markers = '';
var decodeItem = function(item, positioned) {
if (item == 'all') {
return -1;
}
if (typeof item == 'string') {
var matches = /^every(\d+)(?:\[(\d+):(\d+)\])?$/.exec(item);
if (matches) {
var every = parseInt(matches[1], 10);
return (matches[2] && matches[3] ?
(positioned ? Math.max(0.0, Math.min(1.0, matches[2])) : matches[2]) + ':' +
(positioned ? Math.max(0.0, Math.min(1.0, matches[3])) : matches[3]) + ':' +
every : -every);
}
}
if ($.isArray(item)) {
item = $.map(item, function(v, i) {
return (positioned ? Math.max(0.0, Math.min(1.0, v)) : v);
});
return item.join(':') + (item.length < 2 ? ':' : '');
}
return item;
};
var escapeText = function(value) {
return value.replace(/,/g, '\\,');
};
for (var i = 0; i < options.markers.length; i++) {
var marker = options.markers[i];
var shape = SHAPES[marker.shape] || marker.shape;
var placement = '';
if (marker.placement) {
var placements = $.makeArray(marker.placement);
for (var j = 0; j < placements.length; j++) {
placement += PLACEMENTS[placements[j]] || '';
}
}
markers += '|' + (marker.positioned ? '@' : '') + shape +
('AfNt'.indexOf(shape) > -1 ? escapeText(marker.text || '') : '') + ',' +
$.gchart.color(marker.color) + ',' +
marker.series + ',' + decodeItem(marker.item, marker.positioned) +
',' + marker.size + ',' + (PRIORITIES[marker.priority] != null ?
PRIORITIES[marker.priority] : marker.priority) +
(placement || marker.offsets ? ',' + placement +
':' + (marker.offsets && marker.offsets[0] ? marker.offsets[0] : '') +
':' + (marker.offsets && marker.offsets[1] ? marker.offsets[1] : '') : '');
}
for (var i = 0; i < options.ranges.length; i++) {
markers += '|' + (options.ranges[i].vertical ? 'R' : 'r') + ',' +
$.gchart.color(options.ranges[i].color) + ',0,' +
options.ranges[i].start + ',' +
(options.ranges[i].end || options.ranges[i].start + 0.005);
}
for (var i = 0; i < options.series.length; i++) {
if (options.series[i].fillColor) {
var fills = ($.isArray(options.series[i].fillColor) ?
options.series[i].fillColor : [options.series[i].fillColor]);
for (var j = 0; j < fills.length; j++) {
if (typeof fills[j] == 'string') {
markers += '|b,' + $.gchart.color(options.series[i].fillColor) +
',' + i + ',' + (i + 1) + ',0';
}
else {
var props = ($.isArray(fills[j]) ? fills[j] : [fills[j].color, fills[j].range]);
markers += '|B,' + $.gchart.color(props[0]) +
',' + i + ',' + props[1] + ',0';
}
}
}
}
return (markers ? '&chm=' + markers.substr(1) : '');
},
/* Generate dynamic icon parameters.
@param options (object) the current instance settings
@return (string) the icons parameters */
_addIcons: function(options) {
var icons = '';
var decodeItem = function(item) {
if (item == 'all') {
return item;
}
if (typeof item == 'string') {
if (/^every(\d+)$/.exec(item)) {
return item.replace(/every/, 'every,');
}
}
if ($.isArray(item)) {
return 'range,' + item.join(',');
}
return item;
};
for (var i = 0; i < options.icons.length; i++) {
var icon = options.icons[i];
icons += '|y;s=' + icon.name + ';d=' + icon.data +
(icon.position ? '' : ';ds=' + icon.series + ';dp=' + decodeItem(icon.item)) +
(icon.zIndex ? ';py=' + icon.zIndex : '') +
(icon.position ? ';po=' + icon.position.join(',') : '') +
(icon.offsets ? ';of=' + icon.offsets.join(',') : '');
}
return (icons ? '&chem=' + icons.substr(1) : '');
},
/* Update the Google charting div with the new settings.
@param target (element) the containing division
@param options (object) the new settings for this Google chart instance */
_updateChart: function(target, options) {
options._src = this._generateChart(options);
if (options.usePost) {
var form = '<form action="http://chart.apis.google.com/chart?' +
Math.floor(Math.random() * 1e8) + '" method="POST">';
var pattern = /(\w+)=([^&]*)/g;
var match = pattern.exec(options._src);
while (match) {
form += '<input type="hidden" name="' + match[1] + '" value="' +
($.inArray(match[1], ['chdl', 'chl', 'chtt', 'chxl']) > -1 ?
decodeURIComponent(match[2]) : match[2]) + '">';
match = pattern.exec(options._src);
}
form += '</form>';
target = $(target);
target.empty();
var ifr = $('<iframe></iframe>').appendTo(target).css({width: '100%', height: '100%'});
var doc = ifr.contents()[0]; // Write iframe directly
doc.open();
doc.write(form);
doc.close();
ifr.show().contents().find('form').submit();
}
else {
var img = $(new Image()); // Prepare to load chart image in background
img.load(function() { // Once loaded...
$(target).find('img').remove().end().append(this); // Replace
if (options.onLoad) {
if (options.provideJSON) { // Retrieve JSON details
$.getJSON(options._src + '&chof=json&callback=?',
function(data) {
options.onLoad.apply(target, [$.gchart._normaliseRects(data)]);
});
}
else {
options.onLoad.apply(target, []);
}
}
});
$(img).attr('src', options._src);
}
},
/* Ensure that rectangle coords go from min to max.
@param jsonData (object) the JSON description of the chart
@return (object) the normalised JSON description */
_normaliseRects: function(jsonData) {
if (jsonData && jsonData.chartshape) {
for (var i = 0; i < jsonData.chartshape.length; i++) {
var shape = jsonData.chartshape[i];
if (shape.type == 'RECT') {
if (shape.coords[0] > shape.coords[2]) {
var temp = shape.coords[0];
shape.coords[0] = shape.coords[2];
shape.coords[2] = temp;
}
if (shape.coords[1] > shape.coords[3]) {
var temp = shape.coords[1];
shape.coords[1] = shape.coords[3];
shape.coords[3] = temp;
}
}
}
}
return jsonData;
},
/* Encode all series with text encoding.
@param options (object) the settings for this Google chart instance
@return (string) the encoded series data */
_textEncoding: function(options) {
var minValue = (options.minValue == $.gchart.calculate ?
this._calculateMinValue(options.series) : options.minValue);
var maxValue = (options.maxValue == $.gchart.calculate ?
this._calculateMaxValue(options.series) : options.maxValue);
var data = '';
for (var i = 0; i < options.series.length; i++) {
data += '|' + this._textEncode(options.series[i], minValue, maxValue);
}
return 't' + (options.visibleSeries || '') + ':' + data.substr(1);
},
/* Encode values in text format: numeric 0.0 to 100.0, comma separated, -1 for null
@param series (object) details about the data values to encode
@param minValue (number) the minimum possible data value
@param maxValue (number) the maximum possible data value
@return (string) the encoded data values */
_textEncode: function(series, minValue, maxValue) {
minValue = (series.minValue != null ? series.minValue : minValue);
maxValue = (series.maxValue != null ? series.maxValue : maxValue);
var factor = 100 / (maxValue - minValue);
var data = '';
for (var i = 0; i < series.data.length; i++) {
data += ',' + (series.data[i] == null || isNaN(series.data[i]) ? '-1' :
Math.round(factor * (series.data[i] - minValue) * 100) / 100);
}
return data.substr(1);
},
/* Encode all series with scaled text encoding.
@param options (object) the settings for this Google chart instance
@return (string) the encoded series data */
_scaledEncoding: function(options) {
var minValue = (options.minValue == $.gchart.calculate ?
this._calculateMinValue(options.series) : options.minValue);
var maxValue = (options.maxValue == $.gchart.calculate ?
this._calculateMaxValue(options.series) : options.maxValue);
var data = '';
var minMax = '';
for (var i = 0; i < options.series.length; i++) {
data += '|' + this._scaledEncode(options.series[i], minValue);
minMax += ',' + (options.series[i].minValue != null ?
options.series[i].minValue : minValue) +
',' + (options.series[i].maxValue != null ?
options.series[i].maxValue : maxValue);
}
return 't' + (options.visibleSeries || '') + ':' + data.substr(1) +
'&chds=' + minMax.substr(1);
},
/* Encode values in text format: numeric min to max, comma separated, min - 1 for null
@param series (object) details about the data values to encode
@param minValue (number) the minimum possible data value
@return (string) the encoded data values */
_scaledEncode: function(series, minValue) {
minValue = (series.minValue != null ? series.minValue : minValue);
var data = '';
for (var i = 0; i < series.data.length; i++) {
data += ',' + (series.data[i] == null || isNaN(series.data[i]) ?
(minValue - 1) : series.data[i]);
}
return data.substr(1);
},
/* Encode all series with simple encoding.
@param options (object) the settings for this Google chart instance
@return (string) the encoded series data */
_simpleEncoding: function(options) {
var minValue = (options.minValue == $.gchart.calculate ?
this._calculateMinValue(options.series) : options.minValue);
var maxValue = (options.maxValue == $.gchart.calculate ?
this._calculateMaxValue(options.series) : options.maxValue);
var data = '';
for (var i = 0; i < options.series.length; i++) {
data += ',' + this._simpleEncode(options.series[i], minValue, maxValue);
}
return 's' + (options.visibleSeries || '') + ':' + data.substr(1);
},
/* Encode values in simple format: single character,
banded-62 as A-Za-z0-9, _ for null.
@param series (object) details about the data values to encode
@param minValue (number) the minimum possible data value
@param maxValue (number) the maximum possible data value
@return (string) the encoded data values */
_simpleEncode: function(series, minValue, maxValue) {
minValue = (series.minValue != null ? series.minValue : minValue);
maxValue = (series.maxValue != null ? series.maxValue : maxValue);
var factor = 61 / (maxValue - minValue);
var data = '';
for (var i = 0; i < series.data.length; i++) {
data += (series.data[i] == null || isNaN(series.data[i]) ? '_' :
SIMPLE_ENCODING.charAt(Math.round(factor * (series.data[i] - minValue))));
}
return data;
},
/* Encode all series with extended encoding.
@param options (object) the settings for this Google chart instance
@return (string) the encoded series data */
_extendedEncoding: function(options) {
var minValue = (options.minValue == $.gchart.calculate ?
this._calculateMinValue(options.series) : options.minValue);
var maxValue = (options.maxValue == $.gchart.calculate ?
this._calculateMaxValue(options.series) : options.maxValue);
var data = '';
for (var i = 0; i < options.series.length; i++) {
data += ',' + this._extendedEncode(options.series[i], minValue, maxValue);
}
return 'e' + (options.visibleSeries || '') + ':' + data.substr(1);
},
/* Encode values in extended format: double character,
banded-4096 as A-Za-z0-9-., __ for null.
@param series (object) details about the data values to encode
@param minValue (number) the minimum possible data value
@param maxValue (number) the maximum possible data value
@return (string) the encoded data values */
_extendedEncode: function(series, minValue, maxValue) {
minValue = (series.minValue != null ? series.minValue : minValue);
maxValue = (series.maxValue != null ? series.maxValue : maxValue);
var factor = 4095 / (maxValue - minValue);
var encode = function(value) {
return EXTENDED_ENCODING.charAt(value / 64) +
EXTENDED_ENCODING.charAt(value % 64);
};
var data = '';
for (var i = 0; i < series.data.length; i++) {
data += (series.data[i] == null || isNaN(series.data[i]) ? '__' :
encode(Math.round(factor * (series.data[i] - minValue))));
}
return data;
},
/* Determine the minimum value amongst the data values.
@param series (object[]) the series to examine
@return (number) the minimum value therein */
_calculateMinValue: function(series) {
var minValue = 99999999;
for (var i = 0; i < series.length; i++) {
var data = series[i].data;
for (var j = 0; j < data.length; j++) {
minValue = Math.min(minValue, (data[j] == null ? 99999999 : data[j]));
}
}
return minValue;
},
/* Determine the maximum value amongst the data values.
@param series (object[]) the series to examine
@return (number) the maximum value therein */
_calculateMaxValue: function(series) {
var maxValue = -99999999;
for (var i = 0; i < series.length; i++) {
var data = series[i].data;
for (var j = 0; j < data.length; j++) {
maxValue = Math.max(maxValue, (data[j] == null ? -99999999 : data[j]));
}
}
return maxValue;
}
});
/* The definition of a chart axis.
@param axis (string) the axis position: top, bottom, left, right
@param labels (string[]) the labels for this axis
@param positions (number[], optional) the positions of the labels
@param rangeStart (number, optional with next two) start of range
@param rangeEnd (number, optional with above) end of range
@param rangeInterval (number, optional with above) interval between values in the range
@param colour (string, optional) the axis colour
@param alignment (string, optional) the labels' alignment
@param size (number, optional) the labels' size
@param format (object, optional) the labels' number format options */
function GChartAxis(axis, labels, positions, rangeStart, rangeEnd, rangeInterval,
colour, alignment, size, format) {
if (typeof labels == 'number') { // Range instead of labels/positions
format = alignment;
size = colour;
alignment = rangeInterval;
colour = rangeEnd;
rangeInterval = rangeStart;
rangeEnd = positions;
rangeStart = labels;
positions = null;
labels = null;
}
else if (!$.isArray(positions)) { // Optional positions
format = size;
size = alignment;
alignment = colour;
colour = rangeInterval;
rangeInterval = rangeEnd;
rangeEnd = rangeStart;
rangeStart = positions;
positions = null;
}
if (typeof rangeStart == 'string') { // Optional rangeStart/rangeEnd/rangeInterval
format = colour;
size = rangeInterval;
alignment = rangeEnd;
colour = rangeStart;
rangeInterval = null;
rangeEnd = null;
rangeStart = null;
}
if (typeof rangeInterval == 'string') { // Optional rangeInterval
format = size;
size = alignment;
alignment = colour;
colour = rangeInterval;
rangeInterval = null;
}
if (typeof alignment == 'number') { // Optional alignment
format = size;
size = alignment;
alignment = null;
}
this._axis = axis;
this._labels = labels;
this._positions = positions;
this._range = (rangeStart != null ? [rangeStart, rangeEnd, rangeInterval] : null);
this._color = colour;
this._alignment = alignment;
this._size = size;
this._drawing = null;
this._tickColor = null;
this._tickLength = null;
this._format = format;
}
$.extend(GChartAxis.prototype, {
/* Get/set the axis position.
@param axis (string) the axis position: top, bottom, left, right
@return (GChartAxis) the axis object or
(string) the axis position (if no parameters specified) */
axis: function(axis) {
if (arguments.length == 0) {
return this._axis;
}
this._axis = axis;
return this;
},
/* Get/set the axis labels.
@param labels (string[]) the labels for this axis
@return (GChartAxis) the axis object or
(string[]) the axis labels (if no parameters specified) */
labels: function(labels) {
if (arguments.length == 0) {
return this._labels;
}
this._labels = labels;
return this;
},
/* Get/set the axis label positions.
@param positions (number[]) the positions of the labels
@return (GChartAxis) the axis object or
(number[]) the axis label positions (if no parameters specified) */
positions: function(positions) {
if (arguments.length == 0) {
return this._positions;
}
this._positions = positions;
return this;
},
/* Get/set the axis range.
@param rangeStart (number) start of range
@param rangeEnd (number) end of range
@param rangeInterval (number, optional) interval between values in the range
@return (GChartAxis) the axis object or
(number[3]) the axis range start, end, and interval (if no parameters specified) */
range: function(start, end, interval) {
if (arguments.length == 0) {
return this._range;
}
this._range = [start, end, interval];
return this;
},
/* Get/set the axis style.
@param colour (string) the axis colour
@param alignment (string, optional) the labels' alignment
@param size (number, optional) the labels' size
@return (GChartAxis) the axis object or
(object) the axis style with attributes color, alignment, and size
(if no parameters specified) */
style: function(colour, alignment, size) {
if (arguments.length == 0) {
return (!this._color && !this._alignment && !this._size ? null :
{color: this._color, alignment: this._alignment, size: this._size});
}
this._color = colour;
this._alignment = alignment;
this._size = size;
return this;
},
/* Get/set the axis drawing control.
@param drawing (string) the drawing control: line, ticks, both
@return (GChartAxis) the axis object or
(string) the axis drawing control (if no parameters specified) */
drawing: function(drawing) {
if (arguments.length == 0) {
return this._drawing;
}
this._drawing = drawing;
return this;
},
/* Get/set the axis tick style.
@param colour (string) the colour of the tick marks
@param length (number, optional) the length of the tick marks,
negative values draw inside the chart or
(string, optional) list of lengths, comma-separated
@return (GChartAxis) the axis object or
(object) the axis tick style with attributes color and length
(if no parameters specified) */
ticks: function(colour, length) {
if (arguments.length == 0) {
return (!this._tickColor && !this._tickLength ? null :
{color: this._tickColor, length: this._tickLength});
}
this._tickColor = colour;
this._tickLength = length;
return this;
},
/* Get/set the number format for the axis.
@param type (object) containing all these settings or
(string) 'f' for floating point, 'p' for percentage,
'e' for scientific notation, 'c<CUR>' for currency (as specified by CUR)
@param prefix (string, optional) text appearing before the number
@param suffix (string, optional - can only be present if prefix is present)
text appearing after the number
@param precision (number, optional) the number of decimal places
@param showX (boolean, optional) true to show the x-value, false for the y-value
@param zeroes (boolean, optional - can only be present if showX is present)
true to display trailing zeroes
@param separators (boolean, optional - can only be present if showX and zeroes are present)
true to display group separators
@return (GChartAxis) the axis object or
(object) the axis format (if no parameters specified) */
format: function(type, prefix, suffix, precision, showX, zeroes, separators) {
if (arguments.length == 0) {
return this._format;
}
this._format = initNumberFormat(type, prefix, suffix, precision, showX, zeroes, separators);
return this;
}
});
/* Initialise a number format specification. */
function initNumberFormat(type, prefix, suffix, precision, showX, zeroes, separators) {
if (typeof type == 'object') {
return type;
}
if (typeof prefix == 'number') {
separators = showX;
zeroes = precision;
showX = suffix;
precision = prefix;
suffix = '';
prefix = '';
}
if (typeof prefix == 'boolean') {
separators = precision;
zeroes = suffix;
showX = prefix;
precision = 0;
suffix = '';
prefix = '';
}
if (typeof suffix == 'number') {
separators = zeroes;
zeroes = showX;
showX = precision;
precision = suffix;
suffix = '';
}
if (typeof suffix == 'boolean') {
separators = showX;
zeroes = precision;
showX = suffix;
precision = 0;
suffix = '';
}
if (typeof precision == 'boolean') {
separators = zeroes;
zeroes = showX;
showX = precision;
precision = 0;
}
return {type: type, prefix: prefix || '', suffix: suffix || '', precision: precision || '',
showX: showX || false, zeroes: zeroes || false, separators: separators || false};
}
/* jQuery extend now ignores nulls!
@param target (object) the object to extend
@param props (object) the new attributes to add
@return (object) the updated object */
function extendRemove(target, props) {
$.extend(target, props);
for (var name in props) {
if (props[name] == null) {
target[name] = null;
}
}
return target;
}
/* Attach the Google chart functionality to a jQuery selection.
@param command (string) the command to run (optional, default 'attach')
@param options (object) the new settings to use for these Google chart instances
@return (jQuery object) for chaining further calls */
$.fn.gchart = function(options) {
var otherArgs = Array.prototype.slice.call(arguments, 1);
if (options == 'current') {
return $.gchart['_' + options + 'GChart'].
apply($.gchart, [this[0]].concat(otherArgs));
}
return this.each(function() {
if (typeof options == 'string') {
$.gchart['_' + options + 'GChart'].
apply($.gchart, [this].concat(otherArgs));
}
else {
$.gchart._attachGChart(this, options);
}
});
};
/* Initialise the Google chart functionality. */
$.gchart = new GChart(); // singleton instance
})(jQuery);
//}}}
<!--{{{-->
<link rel="shortcut icon" href="/recipes/tscount_public/tiddlers/favicon.ico" />
<link href="/bags/tscount_public/tiddlers.atom" rel="alternate"
type="application/atom+xml" title="tscount's public feed" />
<!--}}}-->
(function() {
var getCSRFToken = function(window) {
// XXX: should not use RegEx - cf.
// http://www.quirksmode.org/js/cookies.html
// https://github.com/TiddlySpace/tiddlyspace/commit/5f4adbe009ed4bda3ce39058a3fb07de1420358d
var regex = /^(?:.*; )?csrf_token=([^(;|$)]*)(?:;|$)/;
var match = regex.exec(document.cookie);
var csrf_token = null;
if (match && (match.length === 2)) {
csrf_token = match[1];
}
return csrf_token;
};
if (typeof config !== 'undefined' && config.extensions &&
config.extensions.tiddlyspace &&
config.extensions.tiddlyspace.getCSRFToken === null) {
config.extensions.tiddlyspace.getCSRFToken = getCSRFToken;
} else {
window.getCSRFToken = getCSRFToken;
}
})(window);
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
ColorPalette
StyleSheet
SiteSubtitle
GettingStarted
SiteTitle
MainMenu
SiteIcon
DefaultTiddlers
ViewTemplate
PageTemplate
SideBarOptions
EditTemplate
SiteInfo
SideBarTabs
ToolbarCommands
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>This Space</title>
<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
</head>
<body>
<div id="container">
<div id="text-html" class="main section">
<a class="app" href="/">home</a>
<div class="left">
<h2>About this space <button class='toggleNext'></button></h2>
<div id="siteinfo"></div>
<h2>Site Icon</h2>
<div>
<img id="siteicon" class="siteicon">
<form id="upload" method="POST" enctype="multipart/form-data">
<input type="hidden" name="title" value="SiteIcon" />
<input type="hidden" name="tags" value="excludeLists">
<input type="hidden" name="csrf_token" class="csrf" />
<input type="file" name="file" accept="image/*" />
<input class="btn" type="submit" value="upload" />
</form>
<div id="dropzone">Drop file here
<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
</div>
</div>
<h2>Vital Statistics</h2>
<div id="info">please wait while information is loaded about this space...</div>
</div>
<div class="right">
<div class="ts-membership">
<h2>
Add Member
<a href="http://docs.tiddlyspace.com/What%20is%20a%20member%3F" title="What is a Member?" class="help">What is a Member?</a>
</h2>
<div>
<p>Add a new member to your space by entering their name below. Enter a space name instead and prefix with @ to add everyone who is already a member of that space.</p>
<form class="ts-members">
<input class="inputBox" type="text" name="username">
<input type="submit" value="Add Member" class="btn" />
</form>
</div>
<h2>
Existing Members <button class='toggleNext'></button>
</h2>
<div>
Your space currently has the following members:
<ul class="ts-members"></ul>
</div>
<h2>
Include Space
<a class="help" href="http://docs.tiddlyspace.com/What%20is%20space%20inclusion%3F" title="What is inclusion?">What is Inclusion?</a>
</h2>
<form class="ts-includes">
<input class="inputBox" type="text" name="spacename">
<input type="submit" value="Include Space" class="btn" />
</form>
</div>
<div>
<h2>Included Spaces <button class='toggleNext'></button></h2>
<div>
This space includes the following spaces:
<ul class="ts-includes"></ul>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
<script src='/bags/common/tiddlers/backstage.js'></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src='/bags/tiddlyspace/tiddlers/TiddlySpaceCSRF'></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src="/bags/common/tiddlers/ts.js"></script>
<script src="/status.js"></script>
<script src="/bags/common/tiddlers/space.js"></script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
A space with some automated info on how many users and spaces there are, via SomeInfo
/***
|''Name''|ErrorHandlerPlugin|
|''Version''|0.4.3|
|''Author''|Jon Robson|
|''Description''|Localised tiddler save errors including edit conflict resolution.|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
tiddlyspace.getLocalTitle = function(title, workspace, suffix) {
var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
if(!suffix) {
var isPublic = endsWith(workspace, "_public");
suffix = tiddlyspace.resolveSpaceName(workspace);
if(currentSpace == suffix) {
suffix = isPublic ? "public" : "private";
} else {
suffix = "@%0".format(suffix);
}
}
return "%0 *(%1)*".format(title, suffix);
};
var sssp = config.extensions.ServerSideSavingPlugin;
var msgs = config.messages.editConflict = {
loading: "Loading..",
resolve: "[[Edit Conflict]]@glossary: this tiddler may have been changed by someone else.",
reviewDiff: "review (recommended)",
reviewDiffTooltip: "review changes made to this tiddler",
reviewDiffError: "error retrieving revision.",
save: "overwrite",
saveTooltip: "make this revision the top revision of this tiddler",
discard: "cancel",
discardTooltip: "undo changes to this tiddler and get most recent version",
diffTitle: "%0",
diffFieldTitle: "%0 - fields",
diffTextTitle: "%0 - text",
updating: "updating your version...",
diffHeader: ["Review the changes that have been made whilst you were editing this tiddler. ",
"Fold relevant changes back into your version.\n",
"{{removed{Red}}} highlight shows content removed. ",
"{{added{Green}}} highlight shows content added.\n"].join(""),
diffTextHeader: "View changes in text",
diffFieldsHeader: "View changes in fields"
};
var plugin = config.extensions.errorHandler = {
diffTags: ["excludeLists", "excludeMissing", "excludeSearch"],
displayMessage: function(message, tiddler, context) {
var desc = context && context.httpStatus ? context.statusText :
sssp.locale.connectionError;
var reportArea = plugin.reportError(tiddler.title);
var msg = $("<div />").appendTo(reportArea);
if(message == "saveConflict") {
wikify(msgs.resolve, msg[0]);
var choiceArea = $("<div />").appendTo(reportArea)[0];
plugin.editConflictHandler(choiceArea, tiddler);
} else {
msg.text(sssp.locale[message].format(tiddler.title, desc));
}
},
editConflictHandler: function(container, tiddler) {
var title = tiddler.title;
var myrev = tiddler.fields["server.page.revision"];
// note user now needs to edit, fix problem and save.
// TODO: make sure this gets reset in save callback
store.getTiddler(title).fields["server.page.revision"] = "false";
var diffBtn = createTiddlyButton(container, msgs.reviewDiff, msgs.reviewDiffTooltip, function(ev) {
var title = $(ev.target).data("title");
plugin.displayDiff(ev.target, store.getTiddler(title), myrev);
});
var saveBtn = createTiddlyButton(container, msgs.save, msgs.saveTooltip, function(ev) {
var title = $(ev.target).data("title");
var tid = store.saveTiddler(store.getTiddler(title));
autoSaveChanges(null, [tid]);
});
var ignoreBtn = createTiddlyButton(container, msgs.discard, msgs.discardTooltip, function(ev) {
var title = $(ev.target).text(msgs.updating).data("title");
plugin.resetToServerVersion(store.getTiddler(title));
});
$([diffBtn, ignoreBtn, saveBtn]).data("title", title);
},
getDiffTiddlerTexts: function(diffText) {
var chunks = diffText.split("\n \n");
if(chunks.length < 2) {
return [chunks[0], ""];
} else {
var diffFieldsText = "{{diff{\n%0\n}}}".format(chunks[0]);
diffText = '{{diff{\n%0\n}}}'.format(chunks.splice(1, chunks.length).join("\n"));
return [diffText, diffFieldsText];
}
},
makeDiffTiddler: function(title, diff) {
var newTiddler = new Tiddler(title);
var tags = plugin.diffTags;
newTiddler.text = msgs.loading;
newTiddler.fields.doNotSave = true;
newTiddler.tags = diff ? tags.concat(["diff"]) : tags;
newTiddler = store.saveTiddler(newTiddler);
$.extend(store.getTiddler(title).fields,
config.defaultCustomFields); // allow option to save it
return newTiddler;
},
displayDiff: function(src, tiddler, latestRevision) {
var adaptor = tiddler.getAdaptor();
var title = tiddler.title;
var ts = new Date().formatString("0hh:0mm:0ss");
var suffix = "edit conflict %0".format(ts);
var diffTitle = tiddlyspace.getLocalTitle(msgs.diffTitle.format(title), "", suffix);
var diffTextTitle = tiddlyspace.getLocalTitle(msgs.diffTextTitle.format(title), "", suffix);
var diffFieldsTitle = tiddlyspace.getLocalTitle(msgs.diffFieldTitle.format(title), "", suffix);
plugin.makeDiffTiddler(diffTextTitle, true);
plugin.makeDiffTiddler(diffFieldsTitle, true);
var newTiddler = plugin.makeDiffTiddler(diffTitle, false);
newTiddler.text = ['%0\n<<slider chkViewDiffText "%1" "%2">>\n',
'<<slider chkViewDiffField "%3" "%4">>'].join("").
format(msgs.diffHeader, diffTextTitle, msgs.diffTextHeader,
diffFieldsTitle, msgs.diffFieldsHeader);
store.saveTiddler(newTiddler);
var callback = function(r) {
var text = plugin.getDiffTiddlerTexts(r);
store.getTiddler(diffTextTitle).text = text[0];
store.getTiddler(diffFieldsTitle).text = text[1];
story.refreshTiddler(diffTitle, null, true);
};
var workspace = "bags/%0".format(tiddler.fields["server.bag"]);
ajaxReq({
type: "get",
dataType: "text",
url: "/diff?format=unified&rev1=%0/%1/%2&rev2=%0/%1".format(workspace, title, latestRevision),
success: callback,
error: function() {
displayMessage(msgs.reviewDiffError);
}
});
story.displayTiddler(src, diffTitle);
},
resetToServerVersion: function(tiddler) {
var adaptor = tiddler.getAdaptor();
var ctx = {
host: tiddler.fields["server.host"],
workspace: "bags/" + tiddler.fields["server.bag"]
};
adaptor.getTiddler(tiddler.title, ctx, null, function(context) {
store.saveTiddler(context.tiddler);
story.refreshTiddler(tiddler.title);
store.setDirty(false);
});
},
reportError: function(title) {
var el = story.getTiddler(title);
if(!el) {
el = story.displayTiddler(null, title);
}
return $("<div />").addClass("error annotation").prependTo(el)[0];
}
};
sssp.reportFailure = function(message, tiddler, context) {
config.options.chkViewDiffText = config.options.chkViewDiffText === undefined ?
true : config.options.chkViewDiffText;
config.options.chkViewDiffFields = config.options.chkViewDiffFields || false;
plugin.displayMessage(message, tiddler, context);
};
})(jQuery);
//}}}
|Date|Users|Spaces|
|20110801|2426|4498|
|20110802|2431|4505|
|20110803|2445|4528|
|20110804|2461|4546|
|20110805|2474|4559|
|20110806|2487|4576|
|20110807|2492|4583|
|20110808|2498|4589|
|20110809|2504|4598|
|20110810|2511|4617|
|20110811|2520|4633|
|20110812|2525|4640|
|20110813|2541|4662|
|20110814|2545|4669|
|20110815|2548|4674|
|20110816|2555|4683|
|20110817|2560|4691|
|20110818|2566|4700|
|20110819|2578|4715|
|20110820|2585|4726|
|20110821|2590|4733|
|20110822|2598|4745|
|20110823|2618|4766|
|20110824|2669|4820|
|20110825|2693|4851|
|20110826|2732|4896|
|20110827|2773|4940|
|20110828|2791|4969|
|20110829|2803|4983|
|20110830|2821|5001|
|20110831|2831|5014|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120201|4364|6907|291|501|278.8|1976.4|
|20120202|4374|6920|240|491|285.9|2369.3|
|20120203|4382|6933|1012|1135|282.8|2182.3|
|20120204|4391|6942|201|297|284.9|2198.4|
|20120205|4398|6951|477|562|278.7|3210.1|
|20120206|4409|6964|554|727|321.4|3490.3|
|20120207|4429|6982|491|838|287.6|1937|
|20120208|4437|6992|362|736|556.5|1977.5|
|20120209|4442|7002|275|481|352.6|1698.3|
|20120210|4453|7015|267|584|287.9|1564.4|
|20120211|4460|7025|361|524|283.1|1904|
|20120212|4466|7033|162|313|287.2|1438.2|
|20120213|4473|7044|478|741|288.4|2070.7|
|20120214|4482|7058|1466|1744|1605|932.1|
|20120215|4491|7069|493|708|287.9|3032|
|20120216|4497|7076|254|483|286|4214|
|20120217|4504|7083|313|494|285.3|2336.3|
|20120218|4509|7089|217|370|284.3|1820.2|
|20120219|4521|7102|278|397|283.8|1896.6|
|20120220|4530|7113|1694|1856|335.1|4166.1|
|20120221|4541|7125|481|1199|1482.8|3515.8|
|20120222|4561|7146|1047|1199|283.1|2606|
|20120223|4566|7155|614|758|286.3|4405.9|
|20120224|4574|7167|295|434|283.8|1537.3|
|20120225|4581|7175|379|524|289.1|1942|
|20120226|4587|7181|366|471|280.5|2424.6|
|20120227|4594|7189|301|436|288.7|3183.1|
|20120228|4606|7198|406|604|285|3324.5|
|20120229|4610|7203|211|371|288.2|2694.5|
|~ViewToolbar|+editTiddler +cloneTiddler > fields refreshTiddler changeToPublic changeToPrivate revisions syncing permalink references jump closeOthers < closeTiddler|
|~EditToolbar|+saveTiddler saveDraft -cancelTiddler deleteTiddler|
|~RevisionToolbar|> fields revert|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130401|6952|10421|91|169|668.7|259|
|20130402|6957|10429|384|484|315.8|8419.25|
|20130403|6962|10435|435|510|328.2|7423.45|
|20130404|6970|10445|267|377|313.9|2778.31|
|20130405|6978|10454|158|247|320.3|17606|
|20130406|6982|10461|232|315|329.4|2935.76|
|20130407|6987|10466|216|271|324|5573.34|
|20130408|6997|10482|482|617|321|10153.3|
|20130409|7008|10496|400|549|344.7|2857.06|
|20130410|7012|10501|382|527|315.3|2822.57|
|20130411|7019|10508|194|317|335.7|2879.47|
|20130412|7056|10545|531|801|312.6|3102.38|
|20130413|7059|10548|69|135|319.2|4077.6|
|20130414|7065|10555|168|376|312.5|326.05|
|20130415|7074|10565|1031|1256|315.4|3004.09|
|20130416|7084|10578|479|659|320.1|2834.56|
|20130421|7096|10595|117|183|
|20130421|7098|10597|145|218|
|20130422|7104|10605|398|498|
|20130423|7110|10611|151|276|
|20130424|7119|10622|224|358|
|20130425|7126|10629|153|246|
|20130426|7135|10643|368|533|
|20130427|7138|10648|132|231|
|20130428|7140|10651|55|98|
|20130429|7148|10663|207|308|
|20130430|7156|10673|203|284|
|Date|Users|Spaces|Created|Modified|
|20111101|3574|5897|366|485|
|20111102|3582|5913|164|249|
|20111103|3594|5931|897|1020|
|20111104|3605|5942|555|734|
|20111105|3609|5948|504|546|
|20111106|3617|5957|182|637|
|20111107|3635|5976|439|636|
|20111108|3645|5991|180|285|
|20111109|3656|6007|177|256|
|20111110|3668|6024|250|317|
|20111111|3678|6035|185|233|
|20111112|3684|6041|158|263|
|20111113|3688|6047|157|204|
|20111114|3690|6050|107|241|
|20111115|3694|6060|298|370|
|20111116|3704|6075|231|315|
|20111117|3718|6091|368|453|
|20111118|3729|6107|303|442|
|20111119|3736|6114|119|163|
|20111120|3742|6120|733|781|
|20111121|3751|6132|224|329|
|20111122|3758|6140|158|248|
|20111123|3765|6149|212|347|
|20111124|3776|6161|614|726|
|20111125|3783|6170|201|281|
|20111126|3795|6184|174|243|
|20111127|3802|6194|139|268|
|20111128|3809|6201|150|266|
|20111129|3820|6210|130|213|
|20111130|3828|6222|235|335|
|Date|Users|Spaces|Created|Modified|
|20111001|3265|5526|223|233|
|20111002|3273|5541|494|529|
|20111003|3282|5549|406|547|
|20111004|3313|5590|1154|1361|
|20111005|3325|5606|355|679|
|20111006|3340|5624|818|1039|
|20111007|3348|5634|726|829|
|20111008|3353|5639|105|251|
|20111009|3357|5643|87|139|
|20111010|3373|5661|1042|1193|
|20111011|3385|5674|306|482|
|20111012|3399|5691|483|587|
|20111013|3411|5703|443|605|
|20111014|3421|5714|628|740|
|20111015|3423|5718|960|1027|
|20111016|3430|5726|656|745|
|20111017|3436|5734|370|516|
|20111018|3446|5745|219|368|
|20111019|3457|5757|370|510|
|20111020|3465|5769|1307|1589|
|20111021|3473|5778|288|409|
|20111022|3483|5789|137|167|
|20111023|3490|5799|558|603|
|20111024|3501|5815|650|808|
|20111025|3520|5838|375|530|
|20111026|3528|5848|677|876|
|20111027|3535|5855|250|350|
|20111028|3544|5864|448|619|
|20111029|3551|5871|585|610|
|20111030|3557|5878|129|191|
|20111031|3566|5887|691|888|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20111201|3839|6237|227|336|0|0|
|20111202|3847|6248|358|535|0|0|
|20111203|3855|6256|121|189|0|0|
|20111204|3860|6261|76|150|0|0|
|20111205|3870|6274|396|515|0|0|
|20111206|3881|6290|235|361|0|0|
|20111207|3890|6300|182|256|0|0|
|20111208|3896|6308|163|261|0|0|
|20111209|3903|6317|151|265|0|0|
|20111210|3908|6323|155|196|0|0|
|20111211|3912|6332|172|264|0|0|
|20111212|3919|6342|683|1858|0|0|
|20111213|3926|6352|638|753|0|0|
|20111214|3929|6359|373|615|0|0|
|20111215|3939|6383|478|722|0|0|
|20111216|3961|6409|775|893|0|0|
|20111217|3968|6415|270|489|0|0|
|20111218|3974|6422|250|307|0|0|
|20111219|3987|6440|540|630|0|0|
|20111220|3996|6452|791|952|1206.2|5709.3|
|20111221|3996|6455|186|275|311.5|2289.2|
|20111222|4005|6474|1323|1392|655|3689.4|
|20111223|4014|6479|1062|1296|303.2|1945.5|
|20111224|4017|6483|67|196|302.4|2568.2|
|20111225|4023|6490|545|605|301.3|3445.3|
|20111226|4025|6495|225|358|304.8|2451.8|
|20111227|4035|6508|330|419|313.5|2613.3|
|20111228|4046|6519|540|954|421.9|1748.1|
|20111229|4065|6535|529|813|441.2|6109.4|
|20111230|4068|6542|104|356|281.9|2889.7|
|20111231|4072|6547|77|137|279.3|2470.2|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120801|5576|8573|222|326|315.6|190.56|
|20120802|5581|8585|393|529|314.4|6985.16|
|20120803|5588|8592|181|290|310.3|6759.74|
|20120804|5591|8596|339|467|318.9|2504.18|
|20120805|5596|8602|94|208|309.5|6823.71|
|20120806|5602|8611|195|316|311.2|2283.92|
|20120807|5607|8622|252|392|310.3|2469.72|
|20120808|5610|8631|497|630|307.3|2463.41|
|20120809|5627|8655|378|539|304.3|2494|
|20120810|5630|8660|110|426|303.4|229.62|
|20120811|5635|8665|215|315|304|9422.31|
|20120812|5643|8673|769|933|508.3|2491.65|
|20120813|5646|8677|264|372|303.3|2478.09|
|20120814|5649|8681|124|267|311.4|2362.09|
|20120815|5651|8685|290|423|315.9|221.57|
|20120816|5656|8693|280|395|310.5|254.06|
|20120817|5661|8698|89|344|312|214.51|
|20120818|5663|8700|43|118|313.7|208.85|
|20120819|5669|8708|125|163|309.1|2567.38|
|20120820|5671|8711|111|201|305.8|2665.18|
|20120821|5677|8719|257|351|311.7|249.78|
|20120822|5683|8727|151|272|306.3|2288.99|
|20120823|5689|8734|187|336|317.1|2484.47|
|20120824|5695|8741|309|589|316|2759.29|
|20120825|5697|8743|100|251|319|8197.96|
|20120826|5702|8748|86|175|496.8|2417.23|
|20120827|5708|8758|433|551|312.5|2333.2|
|20120828|5717|8776|267|374|306.2|251.31|
|20120829|5725|8784|129|224|23202.8|416.41|
|20120830|5736|8797|220|307|312.1|2410.82|
|20120831|5740|8804|157|212|299.6|2299.3|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120101|4078|6553|97|180|281.4|3226.5|
|20120102|4083|6559|92|164|279.6|2398.3|
|20120103|4090|6567|452|646|281.2|1989.8|
|20120104|4103|6581|474|761|287.5|2197.4|
|20120105|4110|6592|575|653|310.9|1707|
|20120106|4116|6608|623|753|281.2|2780.5|
|20120107|4123|6623|2692|2913|282.7|1673.7|
|20120108|4132|6636|906|1048|276|2935.8|
|20120109|4141|6648|316|448|282.4|1991.6|
|20120110|4150|6659|724|962|279.8|922.2|
|20120111|4163|6679|483|640|279.7|1818.2|
|20120112|4166|6683|731|864|278|2130.2|
|20120113|4172|6691|844|987|282.2|1648|
|20120114|4177|6696|138|208|520.8|2574.2|
|20120115|4185|6704|225|337|284.3|2403.9|
|20120116|4197|6718|651|1000|280.8|8031.8|
|20120117|4217|6740|461|890|281.6|2112.5|
|20120118|4230|6755|496|675|285.3|1403.8|
|20120119|4244|6774|428|728|279.2|5650.2|
|20120120|4255|6787|945|1195|495.5|3112.3|
|20120121|4265|6799|308|390|285.9|2696.5|
|20120122|4268|6802|221|411|273.7|4004.9|
|20120123|4283|6820|500|826|293.3|2029.7|
|20120124|4288|6828|876|1093|276.2|2154.5|
|20120125|4307|6838|662|902|287.1|1945.8|
|20120126|4318|6851|421|570|286.9|3188.4|
|20120127|4328|6862|322|543|277.1|4250.8|
|20120128|4331|6866|198|378|714.1|3774.7|
|20120129|4338|6875|254|469|282.8|1173.7|
|20120130|4348|6887|720|903|279.2|1877.5|
|20120131|4357|6900|845|1110|281.1|1877.5|
Welcome to a space providing the basics for the [[jquery google charts plugin|http://keith-wood.name/gChart.html]]. See [[an HTML page|/gChartBasic.html]] for an intro. A plugin, ChartTablePlugin, is provided as an example of how to use the charting to turn a table into a chart.
See also @charts for an alternative.
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120301|4617|7210|250|454|291|5163.2|
|20120302|4626|7222|548|804|289.3|1773|
|20120303|4636|7232|204|384|286.1|1983.8|
|20120304|4641|7238|404|616|289.3|3095.7|
|20120305|4646|7244|329|570|285.1|1868.7|
|20120306|4650|7250|404|698|280.9|4236.6|
|20120307|4656|7259|384|622|314.7|3343.2|
|20120308|4657|7262|294|464|312.7|1875.5|
|20120309|4661|7269|223|315|312.7|1309.1|
|20120310|4667|7275|140|255|326.7|4126|
|20120311|4671|7279|836|990|593|1246.3|
|20120312|4677|7288|354|705|314|3063.6|
|20120313|4709|7325|693|1004|310|3171.6|
|20120314|4717|7333|412|704|318.8|2759.3|
|20120315|4740|7357|573|708|314|2302.1|
|20120316|4749|7372|528|705|309.4|2921.8|
|20120317|4759|7383|201|304|314.8|2022.6|
|20120318|4765|7390|177|277|311.8|0|
|20120319|4772|7399|419|524|314.1|1688.1|
|20120320|4784|7424|810|1041|438.5|2350.7|
|20120322|4804|7445|0|0|312.6|15584.6|
|20120323|4814|7457|254|427|309.5|15693.1|
|20120324|4820|7464|149|236|314.7|15332|
|20120325|4823|7469|575|674|318|15025.1|
|20120326|4834|7481|364|809|311.5|15321.7|
|20120327|4845|7517|830|1068|304.4|15792.1|
|20120328|4860|7532|223|360|472.1|0|
|20120329|4875|7553|442|605|301.7|16295|
|20120330|4878|7561|574|707|827.1|16687.6|
|20120331|4882|7570|295|443|457.9|1598.1|
/***
|''Name''|TiddlySpaceInitialization|
|''Version''|0.7.2|
|''Description''|Initializes new TiddlySpaces the first time they are created|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/blob/master/src/plugins/TiddlySpaceInit.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig RandomColorPalettePlugin chrjs ImageMacroPlugin|
!TODO
* robust error notification and recovery
!MarkupPreHead
<!--{{{-->
<link rel="shortcut icon" href="/recipes/%0_public/tiddlers/favicon.ico" />
<link href="/bags/%0_public/tiddlers.atom" rel="alternate"
type="application/atom+xml" title="%0's public feed" />
<link rel="canonical" href="%1/" />
<!--}}}-->
!Code
***/
//{{{
(function($) {
var versionField = "tiddlyspaceinit_version";
var markupPreHead = store.getTiddlerText(tiddler.title + "##MarkupPreHead", "");
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace;
var tweb = config.extensions.tiddlyweb;
var plugin = config.extensions.TiddlySpaceInit = {
version: "0.6",
SiteTitle: "%0",
SiteSubtitle: "a TiddlySpace",
flagTitle: "%0SetupFlag",
flagWarning: "Please do not modify this tiddler; it was created " +
"automatically upon space creation.",
dispatch: function(ev) {
var title = plugin.flagTitle.format([currentSpace.name]);
config.annotations[title] = plugin.flagWarning;
if(currentSpace.type != "private") {
return;
}
var tiddlers = [];
var tid = store.getTiddler(title);
if(tid) {
curVersion = parseFloat(tid.fields[versionField]);
reqVersion = parseFloat(plugin.version);
if(curVersion < reqVersion) {
plugin.update(curVersion, tid);
tid.fields[versionField] = plugin.version;
tid.incChangeCount();
tid = store.saveTiddler(tid);
tiddlers.push(tid);
}
} else { // first run
tid = new Tiddler(title);
tid.tags = ["excludeLists", "excludeSearch", "excludePublisher"];
tid.fields = $.extend({}, config.defaultCustomFields);
tid.fields[versionField] = plugin.version;
tid.text = "@@%0@@".format([plugin.flagWarning]);
tid = store.saveTiddler(tid);
tiddlers = tiddlers.concat(plugin.firstRun(), tid);
}
autoSaveChanges(null, tiddlers);
},
update: function(curVersion, flagTiddler) {
if(curVersion < 0.2) {
this.createAvatar();
}
if(curVersion < 0.3) {
flagTiddler.tags.pushUnique("excludePublisher"); // XXX: never persisted
}
if(curVersion < 0.5) { // v0.4 was faulty
this.setupMarkupPreHead();
}
if(curVersion < 0.6) {
this.purgeSystemSettings();
}
},
pubTid: {
tags: ["excludeLists", "excludeSearch"],
fields: $.extend({}, config.defaultCustomFields, {
"server.workspace": tiddlyspace.getCurrentWorkspace("public")
})
},
makeTiddlerIfNot: function(tiddler) {
if (!store.tiddlerExists(tiddler.title)) {
$.extend(true, tiddler, plugin.pubTid);
return [store.saveTiddler(tiddler)];
} else {
return [];
}
},
firstRun: function() {
var tiddlers = [];
// generate Site*itle
$.each(["SiteTitle", "SiteSubtitle"], function(i, item) {
var tid = new Tiddler(item);
tid.text = plugin[item].format([currentSpace.name]);
tiddlers.push.apply(tiddlers,
plugin.makeTiddlerIfNot(tid));
});
// generate public ColorPalette
var tid = new Tiddler("ColorPalette");
tid.text = config.macros.RandomColorPalette.generatePalette({
saturation_pale: 0.67, saturation_light: 0.53,
saturation_mid: 0.43, saturation_dark: 0.06,
pale: 0.99, light: 0.85, mid: 0.5, dark: 0.31
},
false);
tiddlers.push.apply(tiddlers, plugin.makeTiddlerIfNot(tid));
this.createAvatar();
this.setupMarkupPreHead();
return tiddlers;
},
// remove _cookie slices (TiddlyWiki 2.6.2 beta 6 remnants)
purgeSystemSettings: function() {
var ss = store.getTiddler("SystemSettings");
if(ss) {
var lines = ss.text.split("\n");
var persistentOptions = $.grep(lines, function(line, i) {
return line.indexOf("_cookie:") == -1;
});
ss.text = persistentOptions.join("\n");
ss = store.saveTiddler(ss);
autoSaveChanges(null, [ss]);
}
},
createAvatar: function() {
var avatar = "SiteIcon";
var host = tweb.host;
var notify = function(xhr, error, exc) {
displayMessage("ERROR: could not create avatar - " + // TODO: i18n
"%0: %1".format([xhr.statusText, xhr.responseText]));
// TODO: resolve!?
};
var pubBag = tiddlyspace.getCurrentBag("public");
var tid = new tiddlyweb.Tiddler(avatar);
tid.bag = new tiddlyweb.Bag(pubBag, host);
var callback = function(data, status, xhr) {}; // avatar already exists; do nothing
var errback = function(xhr, error, exc) {
if(xhr.status != 404) {
return;
}
// copy default avatar
var _notify = function(tid, status, xhr) {
displayMessage("created avatar"); // TODO: i18n
var image = config.macros.image;
if(image && image.refreshImage) {
var uri = "/%0/tiddlers/SiteIcon".
format(tiddlyspace.getCurrentWorkspace("public"));
image.refreshImage(uri);
image.refreshImage("SiteIcon");
}
};
var _callback = function(tid, status, xhr) {
tid.title = avatar;
tid.bag.name = pubBag;
delete tid.etag;
tid.put(_notify, notify); // TODO: add to current session document (via adaptor?)
};
tweb.getUserInfo(function(user) {
var avatarTitle = currentSpace.name == user.name ?
"defaultUserIcon" : "defaultSiteIcon";
var tid = new tiddlyweb.Tiddler(avatarTitle);
tid.bag = new tiddlyweb.Bag("common", host);
tid.get(_callback, notify);
});
};
tid.get(callback, errback);
},
setupMarkupPreHead: function() {
var pubWorkspace = tiddlyspace.getCurrentWorkspace("public");
var existing = store.getTiddler("MarkupPreHead");
if(!existing || existing.fields["server.workspace"] != pubWorkspace) {
tweb.getStatus(function(status) {
var tid = new Tiddler("MarkupPreHead");
tid.text = markupPreHead.format(currentSpace.name, tiddlyspace.getHost(status.server_host,
currentSpace.name));
tid.tags = ["excludeLists"];
tid.fields = $.extend({}, config.defaultCustomFields);
tid.fields["server.workspace"] = pubWorkspace;
tid.fields["server.page.revision"] = "false";
tid = store.saveTiddler(tid);
autoSaveChanges(null, [tid]);
});
}
}
};
$(document).bind("startup", plugin.dispatch);
})(jQuery);
//}}}
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120501|5108|7884|271|379|308.9|1520.9|
|20120502|5109|7886|149|244|310.2|17246.1|
|20120503|5118|7897|757|895|309.8|16748.4|
|20120504|5121|7901|122|228|470.6|16179|
|20120505|5124|7904|51|164|317|17729.9|
|20120506|5126|7906|608|693|313.4|2675.3|
|20120507|5127|7907|56|179|299.8|1772.7|
|20120508|5131|7921|489|584|308.6|16623.9|
|20120509|5137|7928|167|203|312.1|1745.5|
|20120510|5144|7941|259|315|316.9|22066.3|
|20120511|5150|7949|296|340|313|2041.6|
|20120512|5155|7955|151|197|318.4|16909.4|
|20120513|5159|7959|108|141|311.6|16700.6|
|20120514|5164|7969|542|717|322.3|16835.5|
|20120515|5169|7975|277|573|303.5|17525.6|
|20120516|5171|7982|584|656|317.2|1714.7|
|20120517|5178|7990|733|1056|310.2|2010.8|
|20120518|5180|7995|151|239|307.4|16817.1|
|20120519|5183|8001|175|227|309.5|16567.4|
|20120520|5187|8006|113|223|348.4|17946.1|
|20120521|5196|8016|289|383|417.3|18251.6|
|20120522|5201|8024|849|956|306.7|16699.5|
|20120523|5209|8033|1235|1397|318.2|17451|
|20120524|5217|8046|434|624|314.3|17816.8|
|20120525|5223|8056|279|438|396|18118.4|
|20120526|5227|8061|88|146|317.6|16946.2|
|20120527|5230|8065|923|967|311|17099.1|
|20120528|5240|8083|331|417|321.6|16283.4|
|20120529|5250|8099|234|304|308.1|17117.3|
|20120530|5257|8109|232|346|313.4|17976.7|
|20120531|5268|8125|297|401|312.3|16963.3|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120401|4890|7581|372|489|306.9|16411.3|
|20120402|4905|7599|441|581|324.3|17226.6|
|20120403|4912|7626|492|659|390.9|18970.8|
|20120404|4913|7628|132|254|319.5|2121.1|
|20120405|4921|7638|470|595|313.9|18034.1|
|20120406|4929|7650|478|583|321.8|17300|
|20120407|4933|7657|130|211|312.9|16919.3|
|20120408|4935|7659|187|242|318.9|16510.9|
|20120409|4941|7665|220|574|431|16589.9|
|20120410|4944|7669|130|270|308.6|16534.5|
|20120411|4953|7679|264|355|314.7|16114.2|
|20120412|4961|7691|533|677|319.1|16072.5|
|20120413|4964|7695|154|222|315.7|15855.5|
|20120414|4967|7698|356|418|321.1|1949.8|
|20120415|4971|7703|140|194|320.5|16837.2|
|20120416|4983|7715|344|495|316.7|18157.7|
|20120417|4994|7731|315|491|315.9|16157.8|
|20120418|5003|7743|155|266|307.5|17588.5|
|20120419|5008|7750|299|394|307|16133.7|
|20120420|5021|7768|311|833|316.5|18523|
|20120421|5024|7775|216|379|311|1924|
|20120422|5031|7783|655|736|308.2|18209.8|
|20120423|5045|7800|270|426|317.6|17872.5|
|20120424|5054|7812|177|303|316.7|188176|
|20120425|5063|7823|305|467|310.3|2168.3|
|20120426|5068|7834|195|310|308.7|16533|
|20120427|5080|7847|162|254|319.6|17686.9|
|20120428|5082|7850|80|115|761.2|1804.9|
|20120429|5085|7853|511|634|316.4|18143.7|
|20120430|5092|7865|332|501|311|2664|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120701|5454|8372|98|183|306.7|1805.08|
|20120702|5462|8381|443|571|314.6|1738.03|
|20120703|5462|8385|343|533|307.7|1960.01|
|20120704|5466|8390|1403|1664|312.9|233.66|
|20120705|5469|8394|221|347|315.8|216.66|
|20120706|5471|8398|481|615|313.8|2305.35|
|20120707|5475|8407|192|352|310.1|2229.52|
|20120708|5478|8414|232|347|312.7|2278.79|
|20120709|5486|8425|592|729|317|2163.08|
|20120710|5491|8431|373|681|302|2088.5|
|20120711|5492|8436|261|418|316.4|2265.15|
|20120712|5498|8447|328|480|318.3|2257.33|
|20120713|5502|8453|622|742|315.1|2101.33|
|20120714|5507|8459|159|263|302.5|2175.69|
|20120715|5510|8462|177|308|318.4|2214.82|
|20120716|5514|8466|615|728|314|169.84|
|20120717|5519|8476|460|612|306.6|2350.27|
|20120718|5524|8483|292|478|307.9|205.71|
|20120719|5528|8490|300|457|315.4|2424.23|
|20120720|5531|8501|340|447|308.7|2225.42|
|20120721|5532|8502|56|146|318.2|2182.74|
|20120722|5535|8506|105|208|902.2|2193.25|
|20120723|5541|8514|261|369|312.5|2287.9|
|20120724|5544|8520|707|923|312.4|2344.09|
|20120725|5544|8520|81|167|310.7|251.75|
|20120726|5549|8529|178|412|308.4|2483.86|
|20120727|5557|8541|211|295|316.3|7386.29|
|20120728|5561|8545|79|279|725.1|2368.8|
|20120729|5565|8553|115|389|310.3|2454.22|
|20120730|5570|8559|146|277|311|227.33|
|20120731|5572|8563|179|284|310.3|2178.66|
|20120801|5576|8573|222|326|315.6|190.56|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120601|5272|8130|163|273|590.1|168.86|
|20120602|5276|8135|90|168|316.5|1685.82|
|20120603|5281|8141|154|263|312.3|1819.95|
|20120604|5287|8154|253|519|318.1|1702.66|
|20120605|5289|8161|160|252|316.4|1880.38|
|20120606|5297|8171|241|314|310.7|1933.73|
|20120607|5308|8183|355|609|311.1|8711.58|
|20120608|5316|8193|1232|1439|308.5|1837.46|
|20120609|5321|8202|273|343|316.5|839.28|
|20120610|5323|8204|129|235|328.1|1704.39|
|20120611|5333|8217|273|391|311.4|1830.38|
|20120612|5337|8224|259|410|317.8|1886.09|
|20120613|5344|8233|1233|1349|313|1920.06|
|20120614|5351|8236|212|371|311|1947.6|
|20120615|5357|8243|178|241|320.8|1759.63|
|20120616|5359|8246|90|403|311.2|1773.95|
|20120617|5367|8255|189|269|531.1|1738.64|
|20120618|5371|8259|187|319|321|217.89|
|20120619|5380|8270|445|513|308|1750.61|
|20120620|5384|8275|309|494|318.2|1806.74|
|20120621|5396|8291|547|706|321.7|2025.37|
|20120622|5406|8305|1015|1114|321|13003.6|
|20120623|5409|8308|67|179|300.8|1782.84|
|20120624|5412|8313|113|206|317.4|1934.67|
|20120625|5416|8320|1100|1977|309.3|1763.91|
|20120626|5429|8337|324|454|525.8|2565.18|
|20120627|5434|8343|209|363|459.3|1786.76|
|20120628|5441|8354|326|442|327.6|1889.3|
|20120629|5451|8365|217|315|318.9|47302|
|20120630|5453|8370|102|181|311.7|1764.33|
/***
!Notes
This is an experimental tool to process a table and turn it into a line chart using @jquery-gchart
It should be capable of dealing with multiple series. This would translate to a table with multiple columns.
!Code
***/
//{{{
(function($) {
var colorIndex = ['red', 'green', 'blue', 'lime', 'navy', 'olive', 'orange', 'purple'];
var macro = config.macros.charttable = {
handler: function(place, macroName, params, wikifier, paramString) {
var dataSource = params[0] || 'SomeInfo';
var rawData = store.getTiddlerText(dataSource);
var data = macro.parseData(rawData);
macro.drawChart(place, data);
},
parseData: function(data) {
// parse input make dict output
var max = 0;
var min = 9999999;
var lines = data.split("\n");
var struct = lines.shift();
struct = struct.replace(/^\|\s*/, '').replace(/\s*\|\s*$/, '');
var headers = struct.split(/\s*\|\s*/);
headers.shift();
var series = [];
$.each(headers, function(index, header) {
series.push({"label": header, data: [], color: colorIndex[index]});
//series.push({"label": header, data: []});
});
var labels = [];
$.each(lines, function(index, line) {
line = line.replace(/^\|\s*/, '').replace(/\s*\|\s*$/, '');
var chunks = line.split(/\s*\|\s*/);
labels.push(chunks.shift());
$.each(chunks, function(index, chunk) {
var ser = series[index];
chunk = parseInt(chunk);
max = max > chunk ? max : chunk;
min = min < chunk ? min : chunk;
ser.data.push(chunk);
});
});
return {
"max": max,
"min": min,
"labels": labels,
"series": series
};
},
drawChart: function(place, data) {
var container = $("<div />").appendTo(place);
container.gchart({
type: 'line',
height: 250,
maxValue: data.max,
minValue: data.min,
dataLabels: data.labels,
series: $.each(data.series, function(index, item) {
//$.gchart.series(item.title, item.data, item.color);
$.gchart.series(item);
}),
axes: [$.gchart.axis('left', data.min, data.max),
$.gchart.axis('bottom', data.labels)],
legend: 'right',
});
}
};
})(jQuery);
//}}}
|Date|Users|Spaces|
|20101201|705|1697|
|20110101|837|1998|
|20110201|960|2247|
|20110301|1060|2422|
|20110401|1285|2786|
|20110501|1520|3151|
|20110601|1784|3525|
|20110701|2116|4061|
|20110801|2426|4498|
|20110901|2849|5038|
|20111001|3265|5526|
|20111101|3574|5897|
|20111201|3839|6237|
|20120101|4078|6553|
|20120201|4364|6907|
|20120301|4617|7210|
|20120401|4890|7581|
|20120501|5108|7884|
|20120601|5272|8130|
|20120701|5454|8372|
|20120801|5576|8573|
|20120901|5743|8809|
|20121001|5911|9039|
|20121101|6083|9237|
|20121201|6281|9496|
|20130101|6427|9668|
|20130201|6629|9961|
|20130301|6770|10166|
|20130401|6952|10421|
|20130501|7167|10686|
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20121001|5911|9039|190|315|307.1|248.93|
|20121002|5913|9041|161|291|333.9|209.64|
|20121003|5920|9051|270|384|311.6|2385.28|
|20121004|5924|9056|363|477|309.7|2455.63|
|20121005|5926|9058|487|751|309.1|7211.73|
|20121006|5929|9061|52|111|335.7|7007.01|
|20121007|5934|9066|99|211|311|2618.15|
|20121008|5937|9071|224|397|307.8|2477.51|
|20121009|5945|9079|279|397|62696.6|13758.9|
|20121010|5948|9083|154|255|316|7038.93|
|20121011|5953|9089|100|205|1236.2|2848.34|
|20121012|5956|9093|140|297|317.5|2659.44|
|20121013|5960|9097|75|185|314.3|2560.45|
|20121014|5964|9102|430|527|320.3|2447.75|
|20121015|5967|9107|132|207|315.5|2549.82|
|20121016|5974|9114|141|211|319.2|2482.96|
|20121017|5979|9121|140|230|486.9|457.98|
|20121018|5985|9131|335|493|305.2|183.04|
|20121019|5998|9146|277|405|313.6|2392.97|
|20121020|6004|9152|114|199|532.9|3675.41|
|20121021|6008|9156|116|201|903.3|311.74|
|20121022|6023|9171|588|665|310|2334.19|
|20121023|6029|9179|367|456|317|2415.2|
|20121024|6035|9185|153|247|310.6|158.41|
|20121025|6044|9195|236|352|316.1|2577.33|
|20121026|6051|9204|326|401|315.4|2421.04|
|20121027|6054|9207|96|237|5812.1|2498.55|
|20121028|6060|9213|328|422|308.8|234.36|
|20121029|6069|9222|381|632|309.4|2491.3|
|20121030|6073|9226|308|390|310.5|2492.28|
|20121031|6077|9230|144|274|332|2395.53|
/***
|''Name''|TiddlySpaceBackstage|
|''Version''|0.8.0|
|''Description''|Provides a TiddlySpace version of the backstage and a homeLink macro|
|''Status''|@@beta@@|
|''Contributors''|Jon Lister, Jon Robson, Colm Britton|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceBackstage.js|
|''Requires''|TiddlySpaceConfig ImageMacroPlugin TiddlySpaceViewTypes|
!StyleSheet
.tiddler .error.annotation .button{
display: inline-block;
}
#backstageArea {
z-index: 49;
color: white;
background-color: black;
background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #222),color-stop(0.5, #333),color-stop(1, #555));
background: -moz-linear-gradient(center bottom,#222 0%, #333 50%, #555 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222)";
height: 25px;
padding: 0;
}
#backstageButton {
overflow: hidden;
}
#backstageButton #backstageShow,
#backstageButton #backstageHide {
margin: 0px;
padding: 0px;
}
#backstageButton #backstageShow:hover,
#backstageButton #backstageHide:hover {
background: none;
color: none;
}
#backstageButton img,
#backstageButton svg {
width: 24px;
height: 24px;
}
#messageArea {
top: 50px;
}
#backstageToolbar {
position: relative;
}
#backstageArea a {
padding: 0px;
margin-left: 0px;
color: white;
background: none;
}
#backstageArea a:hover {
background-color: white;
}
#backstage ol,
#backstage ul {
padding: auto;
}
#backstageButton a {
margin: 0;
}
.backstagePanelBody ul {
padding: 5px;
margin: 5px;
}
#backstage #backstagePanel {
margin-left: 5%;
padding: 0em;
margin-right: 5%;
}
#backstageToolbar a {
position: relative;
}
#backstageArea a.backstageSelTab,
#backstageToolbar .backstageTask {
line-height: 25px;
color: #767676;
}
.backstageTask .externalImage,
.backstageTask .image {
display: inline;
}
#backstageToolbar a span {
z-index: 2;
}
a.backstageTask {
display: inline;
margin-left: 1em !important;
}
.backstagePanelBody .button {
display: inline-block;
margin-right: 10px;
}
.backstagePanelBody {
margin: 0 0 0 0.6em;
padding: 0.4em 0.5em 1px 0.5em;
}
#backstage table {
margin: auto;
}
#backstage .wizard table {
border: 0px;
margin: 0;
}
#backstage div li.listLink {
border: 0px;
width: 78%;
font-size: 0.7em;
}
#backstage div li.listTitle {
font-weight: bold;
text-decoration: underline;
font-size: 1em;
background: #ccc;
width: 100%;
}
#backstage fieldset {
border: solid 1px [[ColorPalette::Background]];
}
#backstage .viewer table,#backstage table.twtable {
border: 0px;
}
#backstageToolbar img {
padding: 0;
}
#backstage .wizard,
#backstage .wizardFooter {
background: none;
}
.viewer td, .viewer tr, .twtable td, .twtable tr {
border: 1px solid #eee;
}
#backstage .inlineList ul li {
background-color: [[ColorPalette::Background]];
border: solid 1px [[ColorPalette::TertiaryMid]];
display: block;
float: left;
list-style: none;
margin-right: 1em;
padding: 0.5em;
}
.backstageClear, .inlineList form {
clear: both;
display: block;
margin-top: 3em;
}
.tiddlyspaceMenu {
text-align: center;
}
span.chunkyButton {
display: inline-block;
padding: 0;
margin: 0;
border: solid 2px #000;
background-color: #04b;
}
span.chunkyButton a.button, span.chunkyButton a:active.button {
white-space: nowrap;
font-weight: bold;
font-size: 1.8em;
color: #fff;
text-align: center;
padding: 0.5em 0.5em;
margin: 0;
border-style: none;
display: block;
}
span.chunkyButton:hover {
background-color: #014;
}
span.chunkyButton a.button:hover {
border-style: none;
background: none;
color: #fff;
}
#backstage .unpluggedSpaceTab .wizard,
.unpluggedSpaceTab .wizard {
background: white;
border: 2px solid #CCC;
padding: 5px;
}
.syncKey .keyItem {
border: 1px solid black;
display: inline-block;
margin: 0.2em;
padding: 0.1em 0.1em 0.1em 0.1em;
}
.keyHeading {
font-size: 2em;
font-weight: bold;
margin: 0.4em 0em -0.2em;
}
.unpluggedSpaceTab .putToServer,
.unpluggedSpaceTab .notChanged {
display: none;
}
.tiddlyspaceMenu ul {
margin: 0;
padding: 0;
}
.tiddlyspaceMenu ul li {
list-style: none;
}
.unsyncedChanges .unsyncedList {
display: block;
}
.unsyncedList {
display: none;
}
!Code
***/
//{{{
(function ($) {
var name = "StyleSheet" + tiddler.title;
config.shadowTiddlers[name] = "/*{{{*/\n%0\n/*}}}*/".
format(store.getTiddlerText(tiddler.title + "##StyleSheet")); // this accesses the StyleSheet section of the current tiddler (the plugin that contains it)
store.addNotification(name, refreshStyles);
if (!config.extensions.tiddlyweb.status.tiddlyspace_version) { // unplugged
config.extensions.tiddlyweb.status.tiddlyspace_version = "<unknown>";
config.extensions.tiddlyweb.status.server_host = {
url:config.extensions.tiddlyweb.host }; // TiddlySpaceLinkPlugin expects this
}
var disabled_tasks_for_nonmembers = ["tiddlers", "plugins", "batch", "sync"];
var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
var imageMacro = config.macros.image;
if (config.options.chkBackstage === undefined) {
config.options.chkBackstage = false;
}
// Set up Backstage
config.tasks = {};
config.tasks.status = {
text:"status",
tooltip:"TiddlySpace Info",
content:"<<tiddler Backstage##Menu>>"
};
config.tasks.tiddlers = {
text:"tiddlers",
tooltip:"tiddlers control panel",
content:"<<tiddler Backstage##BackstageTiddlers>>"
};
config.tasks.plugins = {
text:"plugins",
tooltip:"Manage installed plugins",
content:"<<tiddler Backstage##Plugins>>"
};
config.tasks.batch = {
text:"batch",
tooltip:"Batch manage public/private tiddlers",
content:"<<tiddler Backstage##BatchOps>>"
};
config.tasks.tweaks = {
text:"tweaks",
tooltip:"Tweak TiddlyWiki behaviors",
content:"<<tiddler Backstage##Tweaks>>"
};
config.tasks.exportTiddlers = {
text:"import/export",
tooltip:"Import/export tiddlers from/to a TiddlyWiki",
content:"<<tiddler Backstage##ImportExport>>"
};
config.tasks.sync = {
text:"sync",
tooltip:"Check Sync status",
content:"<<tiddler Backstage##SpaceUnplugged>>"
};
if (window.location.protocol === "file:") {
config.unplugged = true;
}
config.backstageTasks = ["status", "tiddlers", "plugins",
"batch", "tweaks", "exportTiddlers", "sync"];
config.messages.backstage.prompt = "";
// initialize state
var _show = backstage.show;
backstage.show = function () {
// selectively hide backstage tasks and tabs based on user status
var tasks = $("#backstageToolbar .backstageTask").show();
var bs = backstage.tiddlyspace;
if (!config.unplugged) {
tweb.getUserInfo(function (user) {
if (user.anon) {
jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
var taskIndex = config.backstageTasks.indexOf(task);
if (taskIndex !== -1) {
config.backstageTasks.splice(taskIndex, 1);
}
});
config.messages.memberStatus = bs.locale.loggedout;
} else {
config.messages.memberStatus = readOnly ?
bs.locale.nonmember : bs.locale.member;
}
});
} else {
config.messages.memberStatus = bs.locale.unplugged;
}
// display backstage
return _show.apply(this, arguments);
};
if (readOnly) {
jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
var taskIndex = config.backstageTasks.indexOf(task);
if (taskIndex !== -1) {
config.backstageTasks.splice(taskIndex, 1);
}
});
}
var tasks = config.tasks;
var commonUrl = "/bags/common/tiddlers/%0";
backstage.tiddlyspace = {
locale:{
member:"You are a member of this space.",
nonmember:"You are not a member of this space.",
loggedout:"You are currently logged out of TiddlySpace.",
unplugged:"You are unplugged."
},
showButton:function () {
var showBtn = $("#backstageShow")[0];
var altText = $(showBtn).text();
$(showBtn).empty();
imageMacro.renderImage(showBtn, "backstage.svg",
{ altImage:commonUrl.format("backstage.png"), alt:altText});
},
hideButton:function () {
var hideBtn = $("#backstageHide")[0];
var altText = $(hideBtn).text();
$(hideBtn).empty();
imageMacro.renderImage(hideBtn, "close.svg",
{ altImage:commonUrl.format("close.png"), alt:altText, width:24, height:24 });
}
};
var _init = backstage.init;
backstage.init = function () {
_init.apply(this, arguments);
var init = function (user) {
var bs = backstage.tiddlyspace;
bs.showButton();
bs.hideButton();
};
tweb.getUserInfo(init);
};
var home = config.macros.homeLink = {
locale:{
linkText:"your home space"
},
handler:function (place) {
var container = $("<span />").appendTo(place)[0];
tweb.getUserInfo(function (user) {
if (!user.anon && user.name !== currentSpace) {
createSpaceLink(container, user.name, null, home.locale.linkText);
}
});
}
};
config.macros.exportSpace = {
handler:function (place, macroName, params) {
var filename = params[0] ||
"/tiddlers.wiki?download=%0.html".format(currentSpace);
$('<a class="button">download</a>').// XXX: i18n
attr("href", filename).appendTo(place);
}
};
}(jQuery));
//}}}
|Date|Users|Spaces|
|20110701|2116|4061|
|20110702|2127|4078|
|20110703|2134|4093|
|20110704|2138|4100|
|20110705|2154|4119|
|20110706|2166|4136|
|20110707|2171|4147|
|20110708|2184|4169|
|20110709|2193|4182|
|20110710|2199|4194|
|20110711|2206|4204|
|20110712|2218|4221|
|20110713|2233|4245|
|20110714|2245|4263|
|20110715|2261|4286|
|20110716|2271|4304|
|20110717|2277|4313|
|20110718|2281|4317|
|20110719|2296|4341|
|20110720|2310|4357|
|20110721|2314|4368|
|20110722|2324|4381|
|20110723|2334|4395|
|20110724|2341|4404|
|20110725|2347|4410|
|20110726|2358|4423|
|20110727|2367|4434|
|20110728|2378|4443|
|20110729|2393|4459|
|20110730|2401|4470|
|20110731|2416|4486|
/***
|''Name''|ServerSideSavingPlugin|
|''Description''|server-side saving|
|''Author''|FND|
|''Version''|0.6.5|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/ServerSideSavingPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.3|
|''Keywords''|serverSide|
!Notes
This plugin relies on a dedicated adaptor to be present.
The specific nature of this plugin depends on the respective server.
!Revision History
!!v0.1 (2008-11-24)
* initial release
!!v0.2 (2008-12-01)
* added support for local saving
!!v0.3 (2008-12-03)
* added Save to Web macro for manual synchronization
!!v0.4 (2009-01-15)
* removed ServerConfig dependency by detecting server type from the respective tiddlers
!!v0.5 (2009-08-25)
* raised CoreVersion to 2.5.3 to take advantage of core fixes
!!v0.6 (2010-04-21)
* added notification about cross-domain restrictions to ImportTiddlers
!To Do
* conflict detection/resolution
* rename to ServerLinkPlugin?
* document deletion/renaming convention
!Code
***/
//{{{
(function($) {
readOnly = false; //# enable editing over HTTP
var plugin = config.extensions.ServerSideSavingPlugin = {};
plugin.locale = {
saved: "%0 saved successfully",
saveError: "Error saving %0: %1",
saveConflict: "Error saving %0: edit conflict",
deleted: "Removed %0",
deleteError: "Error removing %0: %1",
deleteLocalError: "Error removing %0 locally",
removedNotice: "This tiddler has been deleted.",
connectionError: "connection could not be established",
hostError: "Unable to import from this location due to cross-domain restrictions."
};
plugin.sync = function(tiddlers) {
tiddlers = tiddlers && tiddlers[0] ? tiddlers : store.getTiddlers();
$.each(tiddlers, function(i, tiddler) {
var changecount = parseInt(tiddler.fields.changecount, 10);
if(tiddler.fields.deleted === "true" && changecount === 1) {
plugin.removeTiddler(tiddler);
} else if(tiddler.isTouched() && !tiddler.doNotSave() &&
tiddler.getServerType() && tiddler.fields["server.host"]) { // XXX: server.host could be empty string
delete tiddler.fields.deleted;
plugin.saveTiddler(tiddler);
}
});
};
plugin.saveTiddler = function(tiddler) {
try {
var adaptor = this.getTiddlerServerAdaptor(tiddler);
} catch(ex) {
return false;
}
var context = {
tiddler: tiddler,
changecount: tiddler.fields.changecount,
workspace: tiddler.fields["server.workspace"]
};
var serverTitle = tiddler.fields["server.title"]; // indicates renames
if(!serverTitle) {
tiddler.fields["server.title"] = tiddler.title;
} else if(tiddler.title != serverTitle) {
return adaptor.moveTiddler({ title: serverTitle },
{ title: tiddler.title }, context, null, this.saveTiddlerCallback);
}
var req = adaptor.putTiddler(tiddler, context, {}, this.saveTiddlerCallback);
return req ? tiddler : false;
};
plugin.saveTiddlerCallback = function(context, userParams) {
var tiddler = context.tiddler;
if(context.status) {
if(tiddler.fields.changecount == context.changecount) { //# check for changes since save was triggered
tiddler.clearChangeCount();
} else if(tiddler.fields.changecount > 0) {
tiddler.fields.changecount -= context.changecount;
}
plugin.reportSuccess("saved", tiddler);
store.setDirty(false);
} else {
if(context.httpStatus == 412) {
plugin.reportFailure("saveConflict", tiddler);
} else {
plugin.reportFailure("saveError", tiddler, context);
}
}
};
plugin.removeTiddler = function(tiddler) {
try {
var adaptor = this.getTiddlerServerAdaptor(tiddler);
} catch(ex) {
return false;
}
var context = {
host: tiddler.fields["server.host"],
workspace: tiddler.fields["server.workspace"],
tiddler: tiddler
};
var req = adaptor.deleteTiddler(tiddler, context, {}, this.removeTiddlerCallback);
return req ? tiddler : false;
};
plugin.removeTiddlerCallback = function(context, userParams) {
var tiddler = context.tiddler;
if(context.status) {
if(tiddler.fields.deleted === "true") {
store.deleteTiddler(tiddler.title);
} else {
plugin.reportFailure("deleteLocalError", tiddler);
}
plugin.reportSuccess("deleted", tiddler);
store.setDirty(false);
} else {
plugin.reportFailure("deleteError", tiddler, context);
}
};
plugin.getTiddlerServerAdaptor = function(tiddler) { // XXX: rename?
var type = tiddler.fields["server.type"] || config.defaultCustomFields["server.type"];
return new config.adaptors[type]();
};
plugin.reportSuccess = function(msg, tiddler) {
displayMessage(plugin.locale[msg].format([tiddler.title]));
};
plugin.reportFailure = function(msg, tiddler, context) {
var desc = (context && context.httpStatus) ? context.statusText :
plugin.locale.connectionError;
displayMessage(plugin.locale[msg].format([tiddler.title, desc]));
};
config.macros.saveToWeb = { // XXX: hijack existing sync macro?
locale: { // TODO: merge with plugin.locale?
btnLabel: "save to web",
btnTooltip: "synchronize changes",
btnAccessKey: null
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
createTiddlyButton(place, this.locale.btnLabel, this.locale.btnTooltip,
plugin.sync, null, null, this.locale.btnAccessKey);
}
};
// hijack saveChanges to trigger remote saving
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
if(window.location.protocol == "file:") {
_saveChanges.apply(this, arguments);
} else {
plugin.sync(tiddlers);
}
};
// override removeTiddler to flag tiddler as deleted -- XXX: use hijack to preserve compatibility?
TiddlyWiki.prototype.removeTiddler = function(title) { // XXX: should override deleteTiddler instance method?
var tiddler = this.fetchTiddler(title);
if(tiddler) {
tiddler.tags = ["excludeLists", "excludeSearch", "excludeMissing"];
tiddler.text = plugin.locale.removedNotice;
tiddler.fields.deleted = "true"; // XXX: rename to removed/tiddlerRemoved?
tiddler.fields.changecount = "1";
this.notify(title, true);
this.setDirty(true);
}
};
// hijack ImportTiddlers wizard to handle cross-domain restrictions
var _onOpen = config.macros.importTiddlers.onOpen;
config.macros.importTiddlers.onOpen = function(ev) {
var btn = $(resolveTarget(ev));
var url = btn.closest(".wizard").find("input[name=txtPath]").val();
if(window.location.protocol != "file:" && url.indexOf("://") != -1) {
var host = url.split("/")[2];
var macro = config.macros.importTiddlers;
if(host != window.location.host) {
btn.text(macro.cancelLabel).attr("title", macro.cancelPrompt);
btn[0].onclick = macro.onCancel;
$('<span class="status" />').text(plugin.locale.hostError).insertAfter(btn);
return false;
}
}
return _onOpen.apply(this, arguments);
};
})(jQuery);
//}}}
/***
|''Name''|RevisionsCommandPlugin|
|''Description''|provides access to tiddler revisions|
|''Author''|FND|
|''Contributors''|Martin Budden|
|''Version''|0.3.3|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/RevisionsCommandPlugin.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/plugins/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Keywords''|serverSide|
!Usage
Extend [[ToolbarCommands]] with {{{revisions}}}.
!Revision History
!!v0.1 (2009-07-23)
* initial release (renamed from experimental ServerCommandsPlugin)
!!v0.2 (2010-03-04)
* suppressed wikification in diff view
!!v0.3 (2010-04-07)
* restored wikification in diff view
* added link to side-by-side diff view
!To Do
* strip server.* fields from revision tiddlers
* resolve naming conflicts
* i18n, l10n
* code sanitizing
* documentation
!Code
***/
//{{{
(function($) {
jQuery.twStylesheet(".diff { white-space: pre, font-family: monospace }",
{ id: "diff" });
var cmd = config.commands.revisions = {
type: "popup",
hideShadow: true,
text: "revisions",
tooltip: "display tiddler revisions",
revTooltip: "", // TODO: populate dynamically?
loadLabel: "loading...",
loadTooltip: "loading revision list",
selectLabel: "select",
selectTooltip: "select revision for comparison",
selectedLabel: "selected",
compareLabel: "compare",
linkLabel: "side-by-side view",
revSuffix: " [rev. #%0]",
diffSuffix: " [diff: #%0 #%1]",
dateFormat: "YYYY-0MM-0DD 0hh:0mm",
listError: "revisions could not be retrieved",
handlePopup: function(popup, title) {
title = this.stripSuffix("rev", title);
title = this.stripSuffix("diff", title);
var tiddler = store.getTiddler(title);
var type = _getField("server.type", tiddler);
var adaptor = new config.adaptors[type]();
var limit = null; // TODO: customizable
var context = {
host: _getField("server.host", tiddler),
workspace: _getField("server.workspace", tiddler)
};
var loading = createTiddlyButton(popup, cmd.loadLabel, cmd.loadTooltip);
var params = { popup: popup, loading: loading, origin: title };
adaptor.getTiddlerRevisionList(title, limit, context, params, this.displayRevisions);
},
displayRevisions: function(context, userParams) {
removeNode(userParams.loading);
if(context.status) {
var callback = function(ev) {
var e = ev || window.event;
var revision = resolveTarget(e).getAttribute("revision");
context.adaptor.getTiddlerRevision(tiddler.title, revision, context,
userParams, cmd.displayTiddlerRevision);
};
var table = createTiddlyElement(userParams.popup, "table");
for(var i = 0; i < context.revisions.length; i++) {
var tiddler = context.revisions[i];
var row = createTiddlyElement(table, "tr");
var timestamp = tiddler.modified.formatString(cmd.dateFormat);
var revision = tiddler.fields["server.page.revision"];
var cell = createTiddlyElement(row, "td");
createTiddlyButton(cell, timestamp, cmd.revTooltip, callback, null,
null, null, { revision: revision });
cell = createTiddlyElement(row, "td", null, null, tiddler.modifier);
cell = createTiddlyElement(row, "td");
createTiddlyButton(cell, cmd.selectLabel, cmd.selectTooltip,
cmd.revisionSelected, null, null, null,
{ index:i, revision: revision, col: 2 });
cmd.context = context; // XXX: unsafe (singleton)!?
}
} else {
$("<li />").text(cmd.listError).appendTo(userParams.popup);
}
},
revisionSelected: function(ev) {
var e = ev || window.event;
e.cancelBubble = true;
if(e.stopPropagation) {
e.stopPropagation();
}
var n = resolveTarget(e);
var index = n.getAttribute("index");
var col = n.getAttribute("col");
while(!index || !col) {
n = n.parentNode;
index = n.getAttribute("index");
col = n.getAttribute("col");
}
cmd.revision = n.getAttribute("revision");
var table = n.parentNode.parentNode.parentNode;
var rows = table.childNodes;
for(var i = 0; i < rows.length; i++) {
var c = rows[i].childNodes[col].firstChild;
if(i == index) {
if(c.textContent) {
c.textContent = cmd.selectedLabel;
} else {
c.text = cmd.selectedLabel;
}
} else {
if(c.textContent) {
c.textContent = cmd.compareLabel;
} else {
c.text = cmd.compareLabel;
}
c.onclick = cmd.compareSelected;
}
}
},
compareSelected: function(ev) {
var e = ev || window.event;
var n = resolveTarget(e);
var context = cmd.context;
context.rev1 = n.getAttribute("revision");
context.rev2 = cmd.revision;
context.tiddler = context.revisions[n.getAttribute("index")];
context.format = "unified";
context.adaptor.getTiddlerDiff(context.tiddler.title, context,
context.userParams, cmd.displayTiddlerDiffs);
},
displayTiddlerDiffs: function(context, userParams) {
var tiddler = context.tiddler;
tiddler.title += cmd.diffSuffix.format([context.rev1, context.rev2]);
tiddler.text = "{{diff{\n" + context.diff + "\n}}}";
tiddler.tags = ["diff"];
tiddler.fields.doNotSave = "true"; // XXX: correct?
if(!store.getTiddler(tiddler.title)) {
store.addTiddler(tiddler);
}
var src = story.getTiddler(userParams.origin);
var tiddlerEl = story.displayTiddler(src, tiddler);
var uri = context.uri.replace("format=unified", "format=horizontal");
var link = $('<a target="_blank" />').attr("href", uri).text(cmd.linkLabel);
$(".viewer", tiddlerEl).prepend(link);
},
displayTiddlerRevision: function(context, userParams) {
var tiddler = context.tiddler;
tiddler.title += cmd.revSuffix.format([tiddler.fields["server.page.revision"]]);
tiddler.fields.doNotSave = "true"; // XXX: correct?
if(!store.getTiddler(tiddler.title)) {
store.addTiddler(tiddler);
}
var src = story.getTiddler(userParams.origin);
story.displayTiddler(src, tiddler);
},
stripSuffix: function(type, title) {
var str = cmd[type + "Suffix"];
var i = str.indexOf("%0");
i = title.indexOf(str.substr(0, i));
if(i != -1) {
title = title.substr(0, i);
}
return title;
}
};
var _getField = function(name, tiddler) {
return tiddler.fields[name] || config.defaultCustomFields[name];
};
})(jQuery);
//}}}
/***
|''Name''|TiddlySpaceFilters|
|''Description''|provide TiddlySpace-specific filter extensions|
|''Author''|Jon Robson|
|''Version''|0.6.1|
|''Status''|@@beta@@|
|''CoreVersion''|2.6.2|
|''Requires''|TiddlySpaceConfig|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<tsList Private>>
<<tsList Public>>
<<tsList Draft>>
}}}
!Code
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var privateBag = tiddlyspace.getCurrentBag("private");
var publicBag = tiddlyspace.getCurrentBag("public");
config.filterHelpers = {
is: {
"private": function(tiddler) {
var bag = tiddler.fields["server.bag"];
return bag == privateBag;
},
"public": function(tiddler) {
var bag = tiddler.fields["server.bag"];
return bag == publicBag;
},
draft: function(tiddler) {
var fields = tiddler.fields;
var bag = fields["server.bag"];
return (privateBag == bag && fields["publish.name"]) ? true : false;
},
local: function(tiddler) {
return config.filterHelpers.is["public"](tiddler) ||
config.filterHelpers.is["private"](tiddler);
},
unsynced: function(tiddler) {
return tiddler ? tiddler.isTouched() : false;
}
}
};
config.filters.is = function(results, match) {
var candidates = store.getTiddlers("title");
var type = match[3];
for (var i = 0; i < candidates.length; i++) {
var tiddler = candidates[i];
var helper = config.filterHelpers.is[type];
if(helper && helper(tiddler)) {
results.pushUnique(tiddler);
}
}
return results;
};
})(jQuery);
//}}}
/***
|''Name''|DiffFormatter|
|''Description''|highlighting of text comparisons|
|''Author''|FND|
|''Version''|0.9.0|
|''Status''|beta|
|''Source''|http://svn.tiddlywiki.org/Trunk/contributors/FND/formatters/DiffFormatter.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Keywords''|formatting|
!Description
Highlights changes in a unified [[diff|http://en.wikipedia.org/wiki/Diff#Unified_format]].
!Notes
Based on Martin Budden's [[DiffFormatterPlugin|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/DiffFormatterPlugin.js]].
!Usage
The formatter is applied to blocks wrapped in <html><code>{{{diff{..}}}</code></html> within tiddlers tagged with "diff".
!Revision History
!!v0.9 (2010-04-07)
* initial release; fork of DiffFormatterPlugin
!StyleSheet
.diff { white-space: pre; font-family: monospace; }
.diff ins, .diff del { display: block; text-decoration: none; }
.diff ins { background-color: #dfd; }
.diff del { background-color: #fdd; }
.diff .highlight { background-color: [[ColorPalette::SecondaryPale]]; }
!Code
***/
//{{{
(function() {
config.shadowTiddlers.StyleSheetDiffFormatter = store.getTiddlerText(tiddler.title + "##StyleSheet");
store.addNotification("StyleSheetDiffFormatter", refreshStyles);
var formatters = [{
name: "diffWrapper",
match: "^\\{\\{diff\\{\n", // XXX: suboptimal
termRegExp: /(.*\}\}\})$/mg,
handler: function(w) {
var el = createTiddlyElement(w.output, "div", null, "diff");
w.subWikifyTerm(el, this.termRegExp);
}
}, {
name: "diffRange",
match: "^(?:@@|[+\\-]{3}) ",
lookaheadRegExp: /^(?:@@|[+\-]{3}) .*\n/mg,
handler: function(w) {
createTiddlyElement(w.output, "div", null, "highlight").
innerHTML = "…";
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
}, {
name: "diffAdded",
match: "^\\+",
termRegExp: /(\n)/mg,
handler: function(w) {
var el = createTiddlyElement(w.output, "ins", null, "added");
w.subWikifyTerm(el, this.termRegExp);
}
}, {
name: "diffRemoved",
match: "^-",
termRegExp: /(\n)/mg,
handler: function(w) {
var el = createTiddlyElement(w.output, "del", null, "removed");
w.subWikifyTerm(el, this.termRegExp);
}
}
];
config.parsers.diffFormatter = new Formatter(formatters);
config.parsers.diffFormatter.format = "diff";
config.parsers.diffFormatter.formatTag = "diff";
})();
//}}}
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20120901|5743|8809|102|156|318|2393.03|
|20120902|5746|8812|182|268|313.9|6417.05|
|20120903|5750|8817|109|235|314.4|213.67|
|20120904|5758|8827|198|301|430.2|2292.89|
|20120905|5764|8835|2230|2344|310|2227.5|
|20120906|5770|8849|310|460|416.3|2430.16|
|20120907|5774|8857|1119|1305|5847.3|2725.81|
|20120908|5788|8872|275|447|567.8|253.52|
|20120909|5790|8876|474|597|317.7|7292.54|
|20120910|5796|8882|1305|1452|307.6|2538|
|20120911|5805|8891|385|1079|325.3|2438.68|
|20120912|5812|8901|317|428|313.3|2367.22|
|20120913|5821|8912|403|586|310.5|2602.61|
|20120914|5829|8923|854|985|321.2|2588.82|
|20120915|5834|8932|381|492|332.3|2605.49|
|20120916|5840|8941|833|1038|304.8|2535.58|
|20120917|5846|8954|1517|1675|329.4|7156.97|
|20120918|5857|8967|553|751|305.5|2592.87|
|20120919|5863|8973|311|424|316.4|2288.38|
|20120920|5869|8980|522|694|316|247.31|
|20120921|5875|8989|398|558|311.7|2462.69|
|20120922|5876|8991|111|194|476.4|2461.37|
|20120923|5879|8994|51|160|311.4|2386.35|
|20120924|5884|9001|233|334|311.4|6757.89|
|20120925|5888|9007|190|315|322.2|2472.67|
|20120926|5899|9020|2297|2500|311.5|2375.99|
|20120927|5902|9023|104|231|319.9|1409.05|
|20120928|5902|9025|429|531|311.7|184.37|
|20120929|5904|9029|233|327|306.4|2432.9|
|20120930|5910|9036|252|347|315.4|2584.39|
|Date|Users|Spaces|
|20120501|5108|7884|
|20120601|5272|8130|
|20120701|5454|8372|
|20120801|5576|8573|
|20120901|5743|8809|
|20121001|5911|9039|
|20121101|6083|9237|
|20121201|6281|9496|
|20130101|6427|9668|
|20130201|6629|9961|
|20130301|6770|10166|
|20130401|6952|10421|
|20130501|7167|10686|
/***
|''Name''|TiddlySpaceCloneCommand|
|''Version''|0.5.8|
|''Description''|provides a toolbar command for cloning external tiddlers|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceCloneCommand.js|
|''Requires''|TiddlySpaceConfig TiddlySpaceFilters|
!Code
***/
//{{{
(function($) {
var cmd = config.commands;
var tiddlyspace = config.extensions.tiddlyspace;
var fieldsCache = {};
cmd.cloneTiddler = {
text: cmd.editTiddler.text,
tooltip: "Create a copy of this tiddler in the current space",
errorMsg: "Error publishing %0: %1",
isEnabled: function(tiddler) {
return !config.filterHelpers.is.local(tiddler) && !readOnly;
},
handler: function(ev, src, title) {
var tiddler = store.getTiddler(title);
if(tiddler) {
fieldsCache[title] = $.extend({}, tiddler.fields);
tiddler.fields["server.workspace"] = tiddlyspace.getCurrentWorkspace(config.options.chkPrivateMode ?
"private" : "public");
tiddler.fields["server.permissions"] = "read, write, create"; // no delete
delete tiddler.fields["server.page.revision"];
delete tiddler.fields["server.title"];
delete tiddler.fields["server.etag"];
// special handling for pseudo-shadow tiddlers
if(tiddlyspace.coreBags.contains(tiddler.fields["server.bag"])) {
tiddler.tags.remove("excludeLists");
}
} else { // ensure workspace is the current space
var el = story.findContainingTiddler(src);
el = $(el);
var fields = el.attr("tiddlyfields");
if(fields) { // inherited via TiddlyLink
fields = fields.decodeHashMap();
fields["server.workspace"] = config.
defaultCustomFields["server.workspace"];
} else {
fields = config.defaultCustomFields;
}
fields = String.encodeHashMap(fields);
el.attr("tiddlyfields", fields);
}
cmd.editTiddler.handler.apply(this, arguments);
if(tiddler) {
tiddler.fields["server.permissions"] += ", delete";
}
return false;
}
};
cmd.editTiddler.isEnabled = function(tiddler) {
return !cmd.cloneTiddler.isEnabled.apply(this, arguments);
};
// hijack cancelTiddler to restore original fields
var _cancelHandler = cmd.cancelTiddler.handler;
cmd.cancelTiddler.handler = function(ev, src, title) {
var tiddler = store.getTiddler(title);
if(tiddler) {
tiddler.fields = fieldsCache[title] || tiddler.fields;
delete fieldsCache[title];
}
return _cancelHandler.apply(this, arguments);
};
// hijack saveTiddler to clear unused fields stash
var _saveHandler = cmd.saveTiddler.handler;
cmd.saveTiddler.handler = function(ev, src, title) {
delete fieldsCache[title];
return _saveHandler.apply(this, arguments);
};
})(jQuery);
//}}}
|Date|Users|Spaces|Created|Modified|
|20130501|7167|10686|155|306|
|20130502|7174|10694|222|454|
|20130503|7186|10707|214|309|
|20130504|7189|10712|130|239|
|20130505|7189|10715|135|219|
|20130506|7198|10725|242|312|
|20130507|7212|10741|205|324|
|20130508|7223|10756|338|438|
|20130509|7234|10768|367|460|
|20130510|7237|10772|266|380|
|20130511|7241|10776|234|287|
|20130512|7246|10783|132|218|
|20130513|7257|10795|324|425|
|20130514|7263|10802|175|297|
|20130515|7280|10822|442|556|
|20130516|7288|10833|383|502|
|20130517|7291|10836|293|390|
|20130518|7293|10838|54|114|
|20130519|7294|10839|77|126|
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
|Date|Users|Spaces|Created|Modified|Tiddlertime|Searchtime|
|20130201|6629|9961|1168|1272|329.7|2774.65|
|20130202|6634|9967|131|275|7234.9|228.61|
|20130203|6639|9972|675|940|320.5|211.84|
|20130204|6645|9982|1081|1280|320.7|2791.75|
|20130205|6653|9990|390|569|321.6|9811.29|
|20130206|6657|9998|602|781|331.1|2863.51|
|20130207|6661|10005|274|529|320|266.4|
|20130208|6669|10015|234|440|322.9|2825.73|
|20130209|6673|10019|175|341|324.7|3021.32|
|20130210|6676|10022|114|246|321.3|271.56|
|20130211|6679|10028|479|663|321.4|2997.02|
|20130212|6686|10036|412|637|1674.8|2928.76|
|20130213|6689|10040|242|610|722|2852.87|
|20130214|6712|10065|779|966|319.7|2863.81|
|20130215|6716|10070|305|581|327.9|2956.03|
|20130216|6720|10075|277|403|319.8|5623.27|
|20130217|6726|10081|258|372|321.2|7791.85|
|20130218|6728|10087|695|782|324.7|2833|
|20130219|6732|10096|398|531|330|3016.27|
|20130220|6739|10106|605|720|327.9|8945.25|
|20130221|6742|10111|2380|2569|326.5|2930.32|
|20130222|6745|10114|358|500|330.9|228.52|
|20130223|6751|10124|418|487|321.7|7251.04|
|20130224|6754|10130|284|455|325.1|3075.38|
|20130225|6756|10133|274|401|322.2|2825.72|
|20130226|6760|10147|444|595|645.1|2969.98|
|20130227|6763|10153|342|490|318.4|2971.1|
|20130228|6767|10160|302|419|318.9|3944.18|
/***
|''Name''|BinaryTiddlersPlugin|
|''Description''|renders base64-encoded binary tiddlers as images or links|
|''Author''|FND|
|''Version''|0.3.2|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/BinaryTiddlersPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
!Code
***/
//{{{
(function($) {
var ctfield = "server.content-type";
var plugin = config.extensions.BinaryTiddlersPlugin = {
isWikiText: function(tiddler) {
var ctype = tiddler.fields[ctfield];
if(ctype) {
if (ctype == 'text/x-tiddlywiki') return true;
return !this.isBinary(tiddler) && !this.isTextual(ctype);
} else {
return true;
}
},
// NB: pseudo-binaries are considered non-binary here
isBinary: function(tiddler) {
var ctype = tiddler.fields[ctfield];
return ctype ? !this.isTextual(ctype) : false;
},
isTextual: function(ctype) {
return ctype.indexOf("text/") == 0
|| this.endsWith(ctype, "+xml")
|| ctype == 'application/json'
|| ctype == 'application/javascript';
},
endsWith: function(str, suffix) {
return str.length >= suffix.length &&
str.substr(str.length - suffix.length) == suffix;
},
isLink: function(tiddler) {
return this.isBinary(tiddler) && tiddler.text.indexOf("<html>") != -1
}
};
// Disable edit for linked tiddlers (for now)
// This will be changed to a GET then PUT
config.commands.editTiddler.isEnabled = function(tiddler) {
var existingTest = config.commands.editTiddler.isEnabled;
if (existingTest) {
return existingTest && !plugin.isLink(tiddler);
} else {
return !plugin.isLink(tiddler);
}
};
// hijack text viewer to add special handling for binary tiddlers
var _view = config.macros.view.views.wikified;
config.macros.view.views.wikified = function(value, place, params, wikifier,
paramString, tiddler) {
var ctype = tiddler.fields["server.content-type"];
if(params[0] == "text" && ctype && ctype !== 'text/x-tiddlywiki' && !tiddler.tags.contains("systemConfig") && !plugin.isLink(tiddler)) {
var el;
if(plugin.isBinary(tiddler)) {
var uri = "data:%0;base64,%1".format([ctype, tiddler.text]); // TODO: fallback for legacy browsers
if(ctype.indexOf("image/") == 0) {
el = $("<img />").attr("alt", tiddler.title).attr("src", uri);
} else {
el = $("<a />").attr("href", uri).text(tiddler.title);
}
} else {
el = $("<pre />").text(tiddler.text);
}
el.appendTo(place);
} else {
_view.apply(this, arguments);
}
};
// hijack edit macro to disable editing of binary tiddlers' body
var _editHandler = config.macros.edit.handler;
config.macros.edit.handler = function(place, macroName, params, wikifier,
paramString, tiddler) {
if(params[0] == "text" && plugin.isBinary(tiddler)) {
return false;
} else {
_editHandler.apply(this, arguments);
}
};
// hijack autoLinkWikiWords to ignore binary tiddlers
var _autoLink = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function() {
return plugin.isWikiText(this) ? _autoLink.apply(this, arguments) : false;
};
})(jQuery);
//}}}