if(console == undefined) { var console = { firebug: "0.4", log: function() {}, logMessage: function() {}, logAssert: function() {}, debug: function() {}, info: function() {}, warn: function() {}, error: function() {}, fail: function() {}, assert: function() {}, assertEquals: function(x,y) {}, assertNotEquals: function(x,y) {}, assertGreater: function(x,y) {}, assertNotGreater: function(x,y) {}, assertLess: function(x,y) {}, assertNotLess: function(x,y) {}, assertContains: function(x,y) {}, assertNotContains: function(x,y) {}, assertTrue: function(x) {}, assertFalse: function(x) {}, assertNull: function(x) {}, assertNotNull: function(x) {}, assertUndefined: function(x) {}, assertNotDefined: function(x) {}, assertInstanceOf: function(x) {}, assertNotInstanceOf: function(x) {}, assertTypeOf: function(x) {}, assertNotTypeOf: function(x) {}, group: function(name) {}, groupEnd: function(name) {}, time: function(name) {}, timeEnd: function(name) {}, count: function(key) {}, trace: function() {} } } /* xmlrpc.js beta version 1 Tool for creating XML-RPC formatted requests in JavaScript Copyright 2001 Scott Andrew LePera scott@scottandrew.com http://www.scottandrew.com/xml-rpc License: You are granted the right to use and/or redistribute this code only if this license and the copyright notice are included and you accept that no warranty of any kind is made or implied by the author. */ function XMLRPCMessage(methodname){ this.method = methodname||"system.listMethods"; this.params = []; return this; } XMLRPCMessage.prototype.setMethod = function(methodName){ if (!methodName) return; this.method = methodName; } XMLRPCMessage.prototype.addParameter = function(data){ if (arguments.length==0) return; this.params[this.params.length] = data; } XMLRPCMessage.prototype.xml = function(){ var method = this.method; // assemble the XML message header var xml = ""; xml += "\n"; xml += "\n"; xml += "" + method+ "\n"; xml += "\n"; // do individual parameters for (var i = 0; i < this.params.length; i++){ var data = this.params[i]; xml += "\n"; xml += "" + XMLRPCMessage.getParamXML(XMLRPCMessage.dataTypeOf(data),data) + "\n"; xml += "\n"; } xml += "\n"; xml += ""; return xml; // for now } XMLRPCMessage.dataTypeOf = function (o){ // identifies the data type var type = typeof(o); type = type.toLowerCase(); switch(type){ case "number": if (Math.round(o) == o) type = "i4"; else type = "double"; break; case "object": var con = o.constructor; if (con == Date) type = "date"; else if (con == Array) type = "array"; else type = "struct"; break; } return type; } XMLRPCMessage.doValueXML = function(type,data){ var xml = "<" + type + ">" + data + ""; return xml; } XMLRPCMessage.doBooleanXML = function(data){ var value = (data==true)?1:0; var xml = "" + value + ""; return xml; } XMLRPCMessage.doDateXML = function(data){ var xml = ""; xml += dateToISO8601(data); xml += ""; return xml; } XMLRPCMessage.doArrayXML = function(data){ var xml = "\n"; for (var i = 0; i < data.length; i++){ xml += "" + XMLRPCMessage.getParamXML(XMLRPCMessage.dataTypeOf(data[i]),data[i]) + "\n"; } xml += "\n"; return xml; } XMLRPCMessage.doStructXML = function(data){ var xml = "\n"; for (var i in data){ xml += "\n"; xml += "" + i + "\n"; xml += "" + XMLRPCMessage.getParamXML(XMLRPCMessage.dataTypeOf(data[i]),data[i]) + "\n"; xml += "\n"; } xml += "\n"; return xml; } XMLRPCMessage.getParamXML = function(type,data){ var xml; switch (type){ case "date": xml = XMLRPCMessage.doDateXML(data); break; case "array": xml = XMLRPCMessage.doArrayXML(data); break; case "struct": xml = XMLRPCMessage.doStructXML(data); break; case "boolean": xml = XMLRPCMessage.doBooleanXML(data); break; default: xml = XMLRPCMessage.doValueXML(type,data); break; } return xml; } function dateToISO8601(date){ // wow I hate working with the Date object var year = new String(date.getYear()); var month = leadingZero(new String(date.getMonth())); var day = leadingZero(new String(date.getDate())); var time = leadingZero(new String(date.getHours())) + ":" + leadingZero(new String(date.getMinutes())) + ":" + leadingZero(new String(date.getSeconds())); var converted = year+month+day+"T"+time; return converted; } function leadingZero(n){ // pads a single number with a leading zero. Heh. if (n.length==1) n = "0" + n; return n; } // fire off an xmlrpc call jQuery.xmlrpc = function(url,method,params,callback,async) { // asynchonous by default if (typeof(async) == 'undefined') async = true; var msg = new XMLRPCMessage(method); for(i=0; i= Math.abs(this.state - this.target)) { this.state = this.target; } else { this.state += movement; } try { this.propagate(); } finally { this.options.onStep.call(this); if (this.target == this.state) { window.clearInterval(this.intervalId); this.intervalId = null; this.options.onComplete.call(this); } } }, // shortcuts play: function() {this.seekFromTo(0, 1)}, reverse: function() {this.seekFromTo(1, 0)} } // merge the properties of two objects Animator.applyDefaults = function(defaults, prefs) { prefs = prefs || {}; var prop, result = {}; for (prop in defaults) result[prop] = prefs[prop] || defaults[prop]; return result; } // make an array from any object Animator.makeArray = function(o) { if (o == null) return []; if (!o.length) return [o]; var result = []; for (var i=0; i 20) return; } }, getStyle: function(state) { state = this.from + ((this.to - this.from) * state); if (this.property == 'filter') return "alpha(opacity=" + Math.round(state*100) + ")"; if (this.property == 'opacity') return state; return Math.round(state) + this.units; } } // animates a colour based style property between two hex values function ColorStyleSubject(els, property, from, to) { this.els = Animator.makeArray(els); this.property = Animator.camelize(property); this.to = this.expandColor(to); this.from = this.expandColor(from); } ColorStyleSubject.prototype = { // parse "#FFFF00" to [256, 256, 0] expandColor: function(color) { var hexColor, red, green, blue; hexColor = ColorStyleSubject.parseColor(color); if (hexColor) { red = parseInt(hexColor.slice(1, 3), 16); green = parseInt(hexColor.slice(3, 5), 16); blue = parseInt(hexColor.slice(5, 7), 16); return [red,green,blue] } if (window.DEBUG) { alert("Invalid colour: '" + color + "'"); } }, getValueForState: function(color, state) { return Math.round(this.from[color] + ((this.to[color] - this.from[color]) * state)); }, setState: function(state) { var color = '#' + ColorStyleSubject.toColorPart(this.getValueForState(0, state)) + ColorStyleSubject.toColorPart(this.getValueForState(1, state)) + ColorStyleSubject.toColorPart(this.getValueForState(2, state)); for (var i=0; i 255) number = 255; var digits = number.toString(16); if (number < 16) return '0' + digits; return digits; } ColorStyleSubject.parseColor.rgbRe = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i; ColorStyleSubject.parseColor.hexRe = /^\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/; // animates between two styles defined using CSS. // if style1 and style2 are present, animate between them, if only style1 // is present, animate between the element's current style and style1 function CSSStyleSubject(els, style1, style2) { els = Animator.makeArray(els); this.subjects = []; if (els.length == 0) return; var prop, toStyle, fromStyle; if (style2) { fromStyle = this.parseStyle(style1, els[0]); toStyle = this.parseStyle(style2, els[0]); } else { toStyle = this.parseStyle(style1, els[0]); fromStyle = {}; for (prop in toStyle) { fromStyle[prop] = CSSStyleSubject.getStyle(els[0], prop); } } // remove unchanging properties var prop; for (prop in fromStyle) { if (fromStyle[prop] == toStyle[prop]) { delete fromStyle[prop]; delete toStyle[prop]; } } // discover the type (numerical or colour) of each style var prop, from, to, units, match, type; for (prop in fromStyle) { if (!toStyle[prop]) { if (window.DEBUG) alert("No to style provided for '" + prop + '"'); continue; } if (from = ColorStyleSubject.parseColor(fromStyle[prop])) { to = ColorStyleSubject.parseColor(toStyle[prop]); type = ColorStyleSubject; } else if(match = CSSStyleSubject.numericalRe.exec(fromStyle[prop])) { from = parseInt(fromStyle[prop]); to = parseInt(toStyle[prop]); type = NumericalStyleSubject; units = match[1] || CSSStyleSubject.numericalRe.exec(toStyle[prop])[1]; } else { if (window.DEBUG) { alert("Unrecognised format for value of " + prop + ": '" + fromStyle[prop] + "'"); } continue; } this.subjects[this.subjects.length] = new type(els, prop, from, to, units); } } CSSStyleSubject.prototype = { // parses "width: 400px; color: #FFBB2E" to {width: "400px", color: "#FFBB2E"} parseStyle: function(style, el) { var rtn = {}; // if style is a rule set if (style.indexOf(":") != -1) { var styles = style.split(";"); for (var i=0; i section ? 1 : 0); } if (this.options.rememberance) { document.location.hash = this.rememberanceTexts[section]; } } }