diff --git a/webtools/new-graph/annotate.cgi b/webtools/new-graph/annotate.cgi new file mode 100755 index 00000000000..1fe9a2cb585 --- /dev/null +++ b/webtools/new-graph/annotate.cgi @@ -0,0 +1,58 @@ +#!/usr/bin/python + +import cgitb; cgitb.enable() + +import sys +import cgi +import time +import re + +from pysqlite2 import dbapi2 as sqlite + +print "Content-type: text/plain\n\n" + +form = cgi.FieldStorage() + +# incoming query string has the following parameters: +# user=name +# (REQUIRED) user that made this annotation +# tbox=foopy +# (REQUIRED) name of the tinderbox to annotate +# data=string +# annotation to record +# time=seconds +# time since the epoch in GMT of this test result; if ommitted, current time at time of script run is used + +tbox = form.getfirst("tbox") +user = form.getfirst("user") +data = form.getfirst("data") +timeval = form.getfirst("time") +if timeval is None: + timeval = int(time.time()) + +if (user is None) or (tbox is None) or (data is None): + print "Bad args" + sys.exit() + +if re.match(r"[^A-Za-z0-9]", tbox): + print "Bad tbox name" + sys.exit() + +db = sqlite.connect("db/" + tbox + ".sqlite") + +try: + db.execute("CREATE TABLE test_results (test_name STRING, test_time INTEGER, test_value FLOAT, test_data BLOB);") + db.execute("CREATE TABLE annotations (anno_user STRING, anno_time INTEGER, anno_string STRING);") + db.execute("CREATE INDEX test_name_idx ON test_results.test_name") + db.execute("CREATE INDEX test_time_idx ON test_results.test_time") + db.execute("CREATE INDEX anno_time_idx ON annotations.anno_time") +except: + pass + +db.execute("INSERT INTO annotations VALUES (?,?,?)", (user, timeval, data)) + +db.commit() + +print "Inserted." + +sys.exit() diff --git a/webtools/new-graph/collect.cgi b/webtools/new-graph/collect.cgi new file mode 100755 index 00000000000..54bd01354eb --- /dev/null +++ b/webtools/new-graph/collect.cgi @@ -0,0 +1,62 @@ +#!/usr/bin/python + +import cgitb; cgitb.enable() + +import sys +import cgi +import time +import re + +from pysqlite2 import dbapi2 as sqlite + +print "Content-type: text/plain\n\n" + +form = cgi.FieldStorage() + +# incoming query string has the following parameters: +# value=n +# (REQUIRED) value to be recorded as the actual test value +# tbox=foopy +# (REQUIRED) name of the tinderbox reporting the value (or rather, the name that is to be given this set of data) +# testname=test +# (REQUIRED) the name of this test +# data=rawdata +# raw data for this test +# time=seconds +# time since the epoch in GMT of this test result; if ommitted, current time at time of script run is used + +value = form.getfirst("value") +data = form.getfirst("data") +tbox = form.getfirst("tbox") +testname = form.getfirst("testname") +timeval = form.getfirst("time") + +if timeval is None: + timeval = int(time.time()) + +if (value is None) or (tbox is None) or (testname is None): + print "Bad args" + sys.exit() + +if re.match(r"[^A-Za-z0-9]", tbox): + print "Bad tbox name" + sys.exit() + +db = sqlite.connect("db/" + tbox + ".sqlite") + +try: + db.execute("CREATE TABLE test_results (test_name STRING, test_time INTEGER, test_value FLOAT, test_data BLOB);") + db.execute("CREATE TABLE annotations (anno_time INTEGER, anno_string STRING);") + db.execute("CREATE INDEX test_name_idx ON test_results(test_name)") + db.execute("CREATE INDEX test_time_idx ON test_results(test_time)") + db.execute("CREATE INDEX anno_time_idx ON annotations(anno_time)") +except: + pass + +db.execute("INSERT INTO test_results VALUES (?,?,?,?)", (testname, timeval, value, data)) + +db.commit() + +print "Inserted." + +sys.exit() diff --git a/webtools/new-graph/getdata-fake.cgi b/webtools/new-graph/getdata-fake.cgi new file mode 100755 index 00000000000..3ad42011166 --- /dev/null +++ b/webtools/new-graph/getdata-fake.cgi @@ -0,0 +1,45 @@ +#!/usr/bin/perl + +print "Content-type: text/plain\n\n"; + +#foreach my $k (keys(%ENV)) { +# print "$k => " . $ENV{$k} . "\n"; +#} + +my $QS = $ENV{"QUERY_STRING"}; +my %query = (); + +{ + my @qp = split /\&/,$QS; + foreach my $q (@qp) { + my @qp1 = split /=/,$q; + $query{$qp1[0]} = $qp1[1]; + } +} + +if (defined($query{"tbox"}) && defined($query{"test"})) { + my $tbox = $query{"tbox"}; + my $test = $query{"test"}; + + print "{ resultcode: 0, results: ["; + + srand(); + + my $lv = 200 + rand (100); + foreach my $k (1 .. 200) { + #my $kv = $k; + #my $v = $k; + my $kv = 1148589000 + ($k*60*5); + my $v = $lv; + $lv = $lv + (rand(10) - 5); + print "$kv, $v, "; + } + print "] }"; +} elsif (defined($query{"tbox"})) { + my $tbox = $query{"tbox"}; + + print "{ resultcode: 0, results: ['$tbox-test1', '$tbox-test2', '$tbox-test3'] }"; +} else { + print "{ resultcode: 0, results: ['tbox1', 'tbox2', 'tbox3'] }"; +} + diff --git a/webtools/new-graph/getdata.cgi b/webtools/new-graph/getdata.cgi new file mode 100755 index 00000000000..8d4f4d48c34 --- /dev/null +++ b/webtools/new-graph/getdata.cgi @@ -0,0 +1,172 @@ +#!/usr/bin/python + +import cgitb; cgitb.enable() + +import os +import sys +import cgi +import time +import re +import gzip + +import cStringIO + +from pysqlite2 import dbapi2 as sqlite + +# +# All objects are returned in the form: +# { +# resultcode: n, +# ... +# } +# +# The ... is dependant on the result type. +# +# Result codes: +# 0 success +# -1 bad tinderbox +# -2 bad test name +# +# incoming query string: +# tbox=name +# tinderbox name +# +# If only tbox specified, returns array of test names for that tinderbox in data +# If invalid tbox specified, returns error -1 +# +# test=testname +# test name +# +# Returns results for that test in .results, in array of [time0, value0, time1, value1, ...] +# Also reteurns .annotations, in array of [time0, string0, time1, string1, ...] +# +# raw=1 +# Same as full results, but includes raw data for test, in form [time0, value0, rawresult0, ...] +# +# starttime=tval +# Start time to return results from, in seconds since GMT epoch +# endtime=tval +# End time, in seconds since GMT epoch +# + +def doError(errCode): + errString = "unknown error" + if errCode == -1: + errString = "bad tinderbox" + elif errCode == -2: + errString = "bad test name" + print "{ resultcode: " + str(errCode) + ", error: '" + errString + "' }" + +db = None + +def doListTinderboxes(fo): + fo.write ("{ resultcode: 0, results: [") + for f in os.listdir("db"): + if f[-7:] == ".sqlite": + fo.write ("'" + f[:-7] + "',") + fo.write ("] }") + +def doListTests(fo, tbox): + fo.write ("{ resultcode: 0, results: [") + + cur = db.cursor() + cur.execute("SELECT DISTINCT(test_name) FROM test_results") + for row in cur: + fo.write ("'" + row[0] + "',") + cur.close() + fo.write ("] }") + +def doSendResults(fo, tbox, test, starttime, endtime, raw): + raws = "" + if raw is not None: + raws = ", test_data" + s1 = "" + s2 = "" + if starttime is not None: + s1 = " AND test_time >= " + starttime + if endtime is not None: + s2 = " AND test_time <= " + endtime + + stmt = "SELECT test_time, test_value" + raws + " FROM test_results WHERE test_name = '" + test + "' " + s1 + s2 + " ORDER BY test_time"; + + fo.write ("{ resultcode: 0, results: [") + + cur = db.cursor() + cur.execute(stmt) + for row in cur: + if raw: + fo.write ("%s,%s,'%s'," % (row[0], row[1], row[2])) + else: + fo.write ("%s,%s," % (row[0], row[1])) + cur.close() + fo.write ("],") + + cur = db.cursor() + if starttime is not None and endtime is not None: + cur.execute("SELECT anno_time, anno_string FROM annotations WHERE anno_time >= " + starttime + " AND anno_time <= " + endtime + " ORDER BY anno_time") + elif starttime is not None: + cur.execute("SELECT anno_time, anno_string FROM annotations WHERE anno_time >= " + starttime + " ORDER BY anno_time") + elif endtime is not None: + cur.execute("SELECT anno_time, anno_string FROM annotations WHERE anno_time <= " + endtime + " ORDER BY anno_time") + else: + cur.execute("SELECT anno_time, anno_string FROM annotations ORDER BY anno_time") + fo.write ("annotations: [") + + for row in cur: + fo.write("%s,'%s'," % (row[0], row[1])) + cur.close() + fo.write ("] }") + +def main(): + doGzip = 0 + try: + if string.find(os.environ["HTTP_ACCEPT_ENCODING"], "gzip") != -1: + doGzip = 1 + except: + pass + + form = cgi.FieldStorage() + + tbox = form.getfirst("tbox") + test = form.getfirst("test") + raw = form.getfirst("raw") + starttime = form.getfirst("starttime") + endtime = form.getfirst("endtime") + + zbuf = cStringIO.StringIO() + zfile = zbuf + if doGzip == 1: + zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) + + if tbox is None: + doListTinderboxes(zfile) + else: + if re.match(r"[^A-Za-z0-9]", tbox): + doError(-1) + return + + dbfile = "db/" + tbox + ".sqlite" + if not os.path.isfile(dbfile): + doError(-1) + return + + global db + db = sqlite.connect(dbfile) + db.text_factory = sqlite.OptimizedUnicode + + if test is None: + doListTests(zfile, tbox) + else: + doSendResults(zfile, tbox, test, starttime, endtime, raw) + + sys.stdout.write("Content-Type: text/plain\n") + if doGzip == 1: + zfile.close() + sys.stdout.write("Content-Encoding: gzip\n") + sys.stdout.write("\n") + + sys.stdout.write(zbuf.getvalue()) + +main() + + diff --git a/webtools/new-graph/graph.html b/webtools/new-graph/graph.html new file mode 100644 index 00000000000..8dab8a76936 --- /dev/null +++ b/webtools/new-graph/graph.html @@ -0,0 +1,78 @@ + + + + Graph + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
Show + +
+ + +
+ +
+
+ +
+ using as a baseline
+
+ +
+ + + + + Link to this graph +      +
+
+ + + +
+
+ + +
+
+ +
+ +
+ +


+


+


+


+


+


+


+
+
Vladimir Vukicevic
+ + diff --git a/webtools/new-graph/js/graph.css b/webtools/new-graph/js/graph.css new file mode 100644 index 00000000000..ae27a6be840 --- /dev/null +++ b/webtools/new-graph/js/graph.css @@ -0,0 +1,58 @@ + +form.graphform { + background-color: #cccccc; + -moz-border-radius: 10px; + padding: 10px; +} + +/* Yuck */ + +.graphform-line, .baseline { + margin-bottom: 5px; +} + +.graphform-first-span { +/* font-weight: bold; */ +} + +#graphforms div .bd .graphform-line .graphform-first-span:after { + content: "For "; +} + +.module + .module .bd .graphform-line .graphform-first-span:after { + content: "and " ! important; +} + +select.tinderbox, select.testname { + width: 200px +} + +.plusminus { + padding: 3px; + vertical-align: middle; +} + +.plusminushidden { + width: 20px; + height: 20px; + visibility: hidden; +} + +.y-axis-label { + font-family: Tahoma, Verdana, Vera Sans, "Bitstream Vera Sans", Arial, Helvetica, sans-serif; + font-size: 75%; + vertical-align: middle; + text-align: right; +} + +.x-axis-label { + font-family: Tahoma, Verdana, Vera Sans, "Bitstream Vera Sans", Arial, Helvetica, sans-serif; + font-size: 75%; + padding: 0px; + vertical-align: top; + text-align: center; +} + +.status { + color: blue; +} diff --git a/webtools/new-graph/js/graph.js b/webtools/new-graph/js/graph.js new file mode 100644 index 00000000000..8a0e9080efe --- /dev/null +++ b/webtools/new-graph/js/graph.js @@ -0,0 +1,1763 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is new graph server code. + * + * The Initial Developer of the Original Code is + * Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vladimir Vukicevic + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// all times are in seconds + +const ONE_HOUR_SECONDS = 60*60; +const ONE_DAY_SECONDS = 24*ONE_HOUR_SECONDS; +const ONE_WEEK_SECONDS = 7*ONE_DAY_SECONDS; +const ONE_YEAR_SECONDS = 365*ONE_DAY_SECONDS; // leap years whatever. + +const MONTH_ABBREV = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; + +//const getdatacgi = "getdata-fake.cgi?"; +//const getdatacgi = "http://localhost:9050/getdata.cgi?"; +const getdatacgi = "getdata.cgi?"; + +// the default average interval +var gAverageInterval = 6*ONE_HOUR_SECONDS; + +function checkErrorReturn(obj) { + if (!obj || obj.resultcode != 0) { + alert ("Error: " + (obj ? (obj.error + "(" + obj.resultcode + ")") : "(nil)")); + return false; + } + return true; +} + +function TinderboxData() { + this.onTinderboxListAvailable = new YAHOO.util.CustomEvent("tinderboxlistavailable"); + this.onTinderboxTestListAvailable = new YAHOO.util.CustomEvent("tinderboxtestlistavailable"); + this.onDataSetAvailable = new YAHOO.util.CustomEvent("datasetavailable"); + + this.tinderboxTests = {}; + this.tinderboxTestData = {}; +} + +TinderboxData.prototype = { + tinderboxes: null, + tinderboxTests: null, + tinderboxTestData: null, + + onTinderboxListAvailable: null, + onTinderboxTestListAvailable: null, + onDataSetAvailable: null, + + defaultLoadRange: null, + + init: function () { + var self = this; + //netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect") + + loadJSONDoc(getdatacgi) + .addCallbacks( + function (obj) { + if (!checkErrorReturn(obj)) return; + self.tinderboxes = obj.results; + self.onTinderboxListAvailable.fire(self.tinderboxes); + }, + function () {alert ("Error talking to getdata.cgi"); }); + }, + + requestTinderboxList: function (callback) { + var self = this; + + if (this.tinderboxes != null) { + callback.call (window, this.tinderboxes); + } else { + var cb = + function (type, args, obj) { + self.onTinderboxListAvailable.unsubscribe(cb, obj); + obj.call (window, args[0]); + }; + + this.onTinderboxListAvailable.subscribe (cb, callback); + } + }, + + requestTestListFor: function (tbox, callback) { + var self = this; + + if ((tbox in this.tinderboxTests) && + (this.tinderboxTests[tbox] != -1)) + { + callback.call (window, tbox, this.tinderboxTests[tbox]); + } else { + // we do this this way so that we only need one + // outstanding request per tinderbox, and we have a way to + // wait for that data to be available + var cb = + function (type, args, obj) { + if (args[0] != tbox) + return; + self.onTinderboxTestListAvailable.unsubscribe(cb, obj); + obj.call (window, args[0], args[1]); + }; + this.onTinderboxTestListAvailable.subscribe (cb, callback); + + if (!(tbox in this.tinderboxTests)) { + this.tinderboxTests[tbox] = -1; + + //netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect") + + loadJSONDoc(getdatacgi + "tbox=" + tbox) + .addCallbacks( + function (obj) { + if (!checkErrorReturn(obj)) return; + + self.tinderboxTests[tbox] = obj.results; + self.onTinderboxTestListAvailable.fire(tbox, self.tinderboxTests[tbox]); + }, + function () {alert ("Error talking to getdata.cgi"); }); + } + } + }, + + requestValueDataSetFor: function (tbox, testname, arg1, arg2, arg3) { + var self = this; + + var startTime = arg1; + var endTime = arg2; + var callback = arg3; + + if (arg1 && arg2 == null && arg3 == null) { + callback = arg1; + if (this.defaultLoadRange) { + startTime = this.defaultLoadRange[0]; + endTime = this.defaultLoadRange[1]; + log ("load range using default", startTime, endTime); + } else { + startTime = null; + endTime = null; + } + } + + if ((tbox in this.tinderboxTestData) && + (testname in this.tinderboxTestData[tbox])) + { + var ds = this.tinderboxTestData[tbox][testname]; + log ("Can maybe use cached?"); + if ((ds.requestedFirstTime == null && ds.requestedLastTime == null) || + (ds.requestedFirstTime <= startTime && + ds.requestedLastTime >= endTime)) + { + log ("Using cached ds"); + callback.call (window, tbox, testname, ds); + return; + } + + // this can be optimized, if we request just the bookend bits, + // but that's overkill + if (ds.firstTime < startTime) + startTime = ds.firstTime; + if (ds.lastTime > endTime) + endTime = ds.lastTime; + } + + var cb = + function (type, args, obj) { + if (args[0] != tbox || + args[1] != testname || + args[3] > startTime || + args[4] < endTime) + { + // not useful for us; there's another + // outstanding request for our time range, so wait for that + return; + } + + self.onDataSetAvailable.unsubscribe(cb, obj); + obj.call (window, args[0], args[1], args[2]); + }; + this.onDataSetAvailable.subscribe (cb, callback); + + //netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect") + + var reqstr = getdatacgi + "tbox=" + tbox + "&test=" + testname; + if (startTime) + reqstr += "&starttime=" + startTime; + if (endTime) + reqstr += "&endtime=" + endTime; + log (reqstr); + loadJSONDoc(reqstr) + .addCallbacks( + function (obj) { + if (!checkErrorReturn(obj)) return; + + var ds = new TimeValueDataSet(obj.results); + ds.requestedFirstTime = startTime; + ds.requestedLastTime = endTime; + if (!(tbox in self.tinderboxTestData)) + self.tinderboxTestData[tbox] = {}; + self.tinderboxTestData[tbox][testname] = ds; + + self.onDataSetAvailable.fire(tbox, testname, ds, startTime, endTime); + }, + function () {alert ("Error talking to getdata.cgi"); }); + }, + + clearValueDataSets: function () { + log ("clearvalueDatasets"); + this.tinderboxTestData = {}; + } +}; + +function TimeDataSet(data) { + this.data = data; +} + +TimeDataSet.prototype = { + data: null, + + indicesForTimeRange: function (startTime, endTime) { + var startIndex = -1; + var endIndex = -1; + + if (this.data[0] > endTime || + this.data[this.data.length-2] < startTime) + return null; + + for (var i = 0; i < this.data.length/2; i++) { + if (startIndex == -1 && this.data[i*2] >= startTime) { + startIndex = i; + } else if (startIndex != -1 && this.data[i*2] > endTime) { + endIndex = i; + return [startIndex, endIndex]; + } + } + + endIndex = (this.data.length/2) - 1; + return [startIndex, endIndex]; + }, +}; + +function TimeValueDataSet(data, color) { + this.data = data; + + this.firstTime = data[0]; + if (data.length > 2) + this.lastTime = data[data.length-2]; + else + this.lastTime = data[0]; + + if (color) { + this.color = color; + } else { + this.color = randomColor(); + } + + log ("new tds:", this.firstTime, this.lastTime); + + this.relativeToSets = new Array(); +} + +TimeValueDataSet.prototype = { + __proto__: new TimeDataSet(), + + firstTime: 0, + lastTime: 0, + data: null, // array: [time0, value0, time1, value1, ...] + relativeTo: null, + + color: "black", + + minMaxValueForTimeRange: function (startTime, endTime) { + var minValue = Number.POSITIVE_INFINITY; + var maxValue = Number.NEGATIVE_INFINITY; + for (var i = 0; i < this.data.length/2; i++) { + var t = this.data[i*2]; + if (t >= startTime && t <= endTime) { + var v = this.data[i*2+1]; + if (v < minValue) + minValue = v; + if (v > maxValue) + maxValue = v; + } + } + + return [minValue, maxValue]; + }, + + // create a new ds that's the average of this ds's values, + // with the average sampled over the given interval, + // at every avginterval/2 + createAverage: function (avginterval) { + if (avginterval <= 0) + throw "avginterval <= 0"; + + if (this.averageDataSet != null && + this.averageInterval == avginterval) + { + return this.averageDataSet; + } + + var newdata = []; + + var time0 = this.data[0]; + var val0 = 0; + var count0 = 0; + + var time1 = time0 + avginterval/2; + var val1 = 0; + var count1 = 0; + + var ns = this.data.length/2; + for (var i = 0; i < ns; i++) { + var t = this.data[i*2]; + var v = this.data[i*2+1]; + if (t > time0+avginterval) { + newdata.push(time0 + avginterval/2); + newdata.push(count0 ? (val0 / count0) : 0); + + // catch up + while (time1 < t) { + time0 += avginterval/2; + time1 = time0; + } + + time0 = time1; + val0 = val1; + count0 = count1; + + time1 = time0 + avginterval/2; + val1 = 0; + count1 = 0; + } + + val0 += v; + count0++; + + if (t > time1) { + val1 += v; + count1++; + } + } + + if (count0 > 0) { + newdata.push(time0 + avginterval/2); + newdata.push(val0 / count0); + } + + var newds = new TimeValueDataSet(newdata, lighterColor(this.color)); + newds.averageOf = this; + + this.averageDataSet = newds; + this.averageInterval = avginterval; + + return newds; + }, + + // create a new dataset with this ds's data, + // relative to otherds + createRelativeTo: function (otherds, absval) { + if (otherds == this) { + log("error, same ds"); + return null; + } + + for each (var s in this.relativeToSets) { + if (s.relativeTo == otherds) + return s; + } + + var firstTime = this.firstTime; + var lastTime = this.lastTime; + + if (otherds.firstTime > firstTime) + firstTime = otherds.firstTime; + if (otherds.lastTime < lastTime) + lastTime = otherds.lastTime; + + var newdata = []; + + var thisidx = this.indicesForTimeRange (firstTime, lastTime); + var otheridx = this.indicesForTimeRange (firstTime, lastTime); + + var o = otheridx[0]; + var ov, ov1, ov2, ot1, ot2; + for (var i = thisidx[0]; i < thisidx[1]; i++) { + var t = this.data[i*2]; + var tv = this.data[i*2+1]; + while (otherds.data[o*2] < t) + o++; + + ot1 = otherds.data[o*2]; + ov1 = otherds.data[o*2+1]; + if (o < otheridx[1]) { + ot2 = otherds.data[o*2+2]; + ov2 = otherds.data[o*2+3]; + } else { + ot2 = ot1; + ov2 = ov1; + } + + + var d = (t-ot1)/(ot2-ot1); + ov = (1-d) * ov1 + d * ov2; + + newdata.push(t); + //log ("i", i, "tv", tv, "ov", ov, "t", t, "ot1", ot1, "ot2", ot2, "ov1", ov1, "ov2", ov2); + //log ("i", i, "tv", tv, "ov", ov, "tv/ov", tv/ov, "ov/tv", ov/tv); + if (absval) { + newdata.push(tv-ov); + } else { + if (tv > ov) + newdata.push((tv/ov) - 1); + else + newdata.push(-((ov/tv) - 1)); + } + } + + var newds = new TimeValueDataSet(newdata, this.color); + newds.relativeTo = otherds; + + this.relativeToSets.push(newds); + + return newds; + }, +}; + +function TimeStringDataSet(data) { + this.data = data; +} + +TimeStringDataSet.prototype = { + __proto__: new TimeDataSet(), + data: null, + + onDataSetChanged: null, + + init: function () { + }, + + addString: function (time, string) { + }, + + removeStringAt: function (index) { + }, +}; + +function Graph() { +} + +Graph.prototype = { + startTime: null, + endTime: null, + + borderTop: 1, + borderLeft: 1, + + yScale: 1, + yOffset: 0, + + backBuffer: null, + frontBuffer: null, + yAxisDiv: null, + xAxisDiv: null, + + dataSets: null, + dataSetIndices: null, + dataSetMinMaxes: null, + + dataSetMinMinVal: 0, + dataSetMaxMaxVal: 0, + + xLabelContainer: null, + xLabelWidth: 100, + xLabelHeight: 50, + + yLabelContainer: null, + yLabelWidth: 50, + yLabelHeight: 50, + + selectionType: "none", + selectionColor: "rgba(0,0,255,0.5)", + selectionCursorTime: null, + selectionStartTime: null, + selectionEndTime: null, + + onSelectionChanged: null, + onCursorMoved: null, + + cursorType: "none", + cursorColor: "rgba(200,200,0,0.7)", + cursorTime: null, + cursorValue: null, + + dirty: true, + valid: false, + + init: function (canvasElement) { + this.frontBuffer = getElement(canvasElement); + this.xLabelContainer = getElement(canvasElement + "-labels-x"); + this.yLabelContainer = getElement(canvasElement + "-labels-y"); + + this.backBuffer = new CANVAS(); + this.backBuffer.width = this.frontBuffer.width; + this.backBuffer.height = this.frontBuffer.height; + + this.overlayBuffer = new CANVAS(); + this.overlayBuffer.width = this.frontBuffer.width; + this.overlayBuffer.height = this.frontBuffer.height; + + this.dataSets = new Array(); + this.dataSetMinMaxes = new Array(); + this.dataSetIndices = new Array(); + + this.onSelectionChanged = new YAHOO.util.CustomEvent("graphselectionchanged"); + this.onCursorMoved = new YAHOO.util.CustomEvent("graphcursormoved"); + }, + + getQueryString: function (prefix) { + var qs = ""; + + qs += prefix + "st=" + this.selectionType; + if (this.selectionType == "range") { + if (this.selectionStartTime != null && this.selectionEndTime != null) + qs += "&" + prefix + "ss=" + this.selectionStartTime + "&" + prefix + "se=" + this.selectionEndTime; + } else if (this.selectionType == "cursor") { + if (this.selectionCursorTime != null) + qs += "&" + prefix + "sc=" + this.selectionCursorTime; + } + + qs += "&" + prefix + "start=" + this.startTime + "&" + prefix + "end=" + this.endTime; + + return qs; + }, + + handleQueryStringData: function (prefix, qsdata) { + // XX should do some more verification that + // qsdata has the members we care about + this.startTime = new Number(qsdata[prefix + "start"]); + this.endTime = new Number(qsdata[prefix + "end"]); + + var st = qsdata[prefix + "st"]; + if (st == "range") { + this.selectionType = "range"; + if (((prefix+"ss") in qsdata) && ((prefix+"se") in qsdata)) { + this.selectionStartTime = new Number(qsdata[prefix + "ss"]); + this.selectionEndTime = new Number(qsdata[prefix + "se"]); + } else { + this.selectionStartTime = null; + this.selectionEndTime = null; + } + } else if (st == "cursor") { + this.selectionType = "Cursor"; + if ((prefix+"sc") in qsdata) + this.selectionCursorTime = new Number(qsdata[prefix + "sc"]); + else + this.selectionCursorTime = null; + } + + this.dirty = true; + }, + + addDataSet: function (ds, color) { + if (this.dataSets.some(function(d) { return (d==ds); })) + return; + + if (color == null) { + if (ds.color != null) { + color = ds.color; + } else { + color = randomColor(); + } + } + + this.dataSets.push(ds); + this.dataSetIndices.push(null); + this.dataSetMinMaxes.push(null); + + this.dirty = true; + }, + + removeDataSet: function (ds) { + for (var i = 0; i < this.dataSets.length; i++) { + if (this.dataSets[i] == ds) { + this.dataSets = Array.splice(this.dataSets, i, 1); + this.dataSetIndices = Array.splice(this.dataSetIndices, i, 1); + this.dataSetMinMaxes = Array.splice(this.dataSetMinMaxes, i, 1); + return; + } + } + }, + + clearDataSets: function () { + this.dataSets = new Array(); + this.dataSetMinMaxes = new Array(); + this.dataSetIndices = new Array(); + + this.dirty = true; + }, + + setTimeRange: function (start, end) { + this.startTime = start; + this.endTime = end; + + this.dirty = true; + }, + + expandTimeRange: function (start, end) { + if (this.startTime == null || start < this.startTime) + this.startTime = start; + if (this.endTime == null || end > this.endTime) + this.endTime = end; + + this.dirty = true; + }, + + setSelectionType: function (stype) { + if (this.selectionType == stype) + return; + + // clear out old listeners + if (this.selectionType == "range") { + YAHOO.util.Event.removeListener (this.frontBuffer, "mousedown", this.selectionMouseDown); + YAHOO.util.Event.removeListener (this.frontBuffer, "mousemove", this.selectionMouseMove); + YAHOO.util.Event.removeListener (this.frontBuffer, "mouseup", this.selectionMouseUp); + YAHOO.util.Event.removeListener (this.frontBuffer, "mouseout", this.selectionMouseOut); + } else if (this.selectionType == "cursor") { + YAHOO.util.Event.removeListener (this.frontBuffer, "mousedown", this.selectionMouseDown); + } + + this.selectionStartTime = null; + this.selectionEndTime = null; + this.selectionCursorTime = null; + + if (stype == "range") { + YAHOO.util.Event.addListener (this.frontBuffer, "mousedown", this.selectionMouseDown, this, true); + YAHOO.util.Event.addListener (this.frontBuffer, "mousemove", this.selectionMouseMove, this, true); + YAHOO.util.Event.addListener (this.frontBuffer, "mouseup", this.selectionMouseUp, this, true); + YAHOO.util.Event.addListener (this.frontBuffer, "mouseout", this.selectionMouseOut, this, true); + + this.selectionType = "range"; + } else if (stype == "cursor") { + YAHOO.util.Event.addListener (this.frontBuffer, "mousedown", this.selectionMouseDown, this, true); + this.selectionType = "cursor"; + } + + this.redrawOverlayOnly(); + }, + + setSelectionColor: function (scolor) { + this.selectionColor = scolor; + this.redrawOverlayOnly(); + }, + + setCursorType: function (type) { + if (this.cursorType == type) + return; + + if (this.cursorType == "free") { + YAHOO.util.Event.removeListener (this.frontBuffer, "mousemove", this.cursorMouseMove); + YAHOO.util.Event.removeListener (this.frontBuffer, "mouseout", this.cursorMouseOut); + } + + if (type == "free") { + YAHOO.util.Event.addListener (this.frontBuffer, "mousemove", this.cursorMouseMove, this, true); + YAHOO.util.Event.addListener (this.frontBuffer, "mouseout", this.cursorMouseOut, this, true); + this.cursorType = "free"; + } else { + this.cursorType = "none"; + } + }, + + recompute: function () { + this.dataSetIndices = []; + this.dataSetMinMaxes = []; + + this.hasRelative = false; + var nonRelative = 0; + + for (var i = 0; i < this.dataSets.length; i++) { + this.dataSetIndices.push (this.dataSets[i].indicesForTimeRange (this.startTime, this.endTime)); + this.dataSetMinMaxes.push (this.dataSets[i].minMaxValueForTimeRange (this.startTime, this.endTime)); + + if (this.dataSets[i].relativeTo != null) + this.hasRelative = true; + else + nonRelative++; + } + + if (this.hasRelative && nonRelative > 1) { + log("More than one non-relative dataset added to graph"); + throw "More than one non-relative dataset added to graph"; + } + + this.dataSetMinMinVal = Number.MAX_VALUE; + this.dataSetMaxMaxVal = Number.MIN_VALUE; + + for each (var dsvals in this.dataSetMinMaxes) { + if (this.dataSetMinMinVal > dsvals[0]) + this.dataSetMinMinVal = dsvals[0]; + if (this.dataSetMaxMaxVal < dsvals[1]) + this.dataSetMaxMaxVal = dsvals[1]; + } + + log ("minmin:", this.dataSetMinMinVal, "maxmax:", this.dataSetMaxMaxVal); + + this.getTimeAxisLabels(); + this.getValueAxisLabels(); + + this.dirty = false; + }, + + autoScale: function () { + if (this.dirty) + this.recompute(); + + var vmin, vmax; + + if (this.hasRelative) { + vmin = Math.floor(this.dataSetMinMinVal); + vmax = Math.ceil(this.dataSetMaxMaxVal); + + if ((vmax - vmin) == 1) + vmin--; + + log ("vmin", vmin, "vmax", vmax); + this.yOffset = vmin; + this.yScale = this.frontBuffer.height / (vmax - vmin); + this.dirty = true; + return; + } + + var delta = this.dataSetMaxMaxVal - this.dataSetMinMinVal; + var scaled = false; + for each (var sfactor in [1000, 500, 250, 100, 25, 10, 1]) { + if (delta > sfactor) { + vmin = this.dataSetMinMinVal - (this.dataSetMinMinVal % sfactor); + vmax = (this.dataSetMaxMaxVal - (this.dataSetMaxMaxVal % sfactor)) + sfactor; + + this.yOffset = vmin; + this.yScale = this.frontBuffer.height / (vmax - vmin); + scaled = true; + break; + } + } + + if (!scaled) { + this.yOffset = this.dataSetMinMinVal; + this.yScale = this.frontBuffer.height / (this.dataSetMaxMaxVal - this.dataSetMinMinVal); + } + + // we have to dirty again, due to the labels + this.dirty = true; + }, + + redraw: function () { + if (this.dirty) + this.recompute(); + + var ctx = this.backBuffer.getContext("2d"); + var cw = this.backBuffer.width; + var ch = this.backBuffer.height; + + var xoffs = this.startTime; + var yoffs = this.yOffset; + + var xscale = cw / (this.endTime - this.startTime); + + var hasAverageDSs = false; + for each (var ds in this.dataSets) { + if ("averageOf" in ds) { + hasAverageDSs = true; + break; + } + } + + for (var i = 0; i < this.dataSets.length; i++) { + // yScale = pixels-per-value + with (ctx) { + clearRect (0, 0, cw, ch); + + // draw gridlines + var yLabelValues = this.getTimeAxisLabels(); + strokeStyle = "#999999"; + for each (var label in yLabelValues) { + // label[1] is the actual value of that label line; we need + // to scale it into place, but we can't just use scale() + // since we want to make sure it's a single-pixel line + var p = Math.round((label[1] - xoffs) * xscale) + 0.5; + beginPath(); + moveTo(p, -0.5); + lineTo(p, this.frontBuffer.height + 0.5); + stroke(); + } + + var xLabelValues = this.getValueAxisLabels(); + for each (var label in xLabelValues) { + var p = Math.round((label[1] - yoffs) * this.yScale) + 0.5; + beginPath(); + moveTo(-0.5, p); + lineTo(this.frontBuffer.width + 0.5, p); + stroke(); + } + + for (var i = 0; i < this.dataSets.length; i++) { + if (this.dataSetIndices[i] == null) { + // there isn't anything in the data set in the given time range + continue; + } + + //log ("ds start end", this.startTime, this.endTime, "timediff:", (this.endTime - this.startTime)); + save(); + scale(xscale, -this.yScale); + translate(0, -ch/this.yScale); + + beginPath(); + + var first = true; + var startIdx = this.dataSetIndices[i][0]; + var endIdx = this.dataSetIndices[i][1]; + + // start one before and go one after if we can, + // so that the plot doesn't have a hole at the start + // and end + if (startIdx > 0) startIdx--; + if (endIdx < ((this.dataSets[i].data.length)/2)) endIdx++; + + for (var j = startIdx; j < endIdx; j++) + { + var t = this.dataSets[i].data[j*2]; + var v = this.dataSets[i].data[j*2+1]; + if (first) { + moveTo (t-xoffs, v-yoffs); + first = false; + } else { + lineTo (t-xoffs, v-yoffs); + } + } + + /* bleh. */ + + restore(); + + if (hasAverageDSs && !("averageOf" in this.dataSets[i])) { + lineWidth = 0.5; + } else { + lineWidth = 1.0; + } + + strokeStyle = colorToRgbString(this.dataSets[i].color); + stroke(); + + lineWidth = 1.0; + } + } + } + + this.redrawOverlayOnly(); + + try { + this.makeLabels(); + } catch (e) { + log(e); + } + + this.valid = true; + }, + + redrawOverlayOnly: function () { + with (this.frontBuffer.getContext("2d")) { + globalCompositeOperation = "copy"; + drawImage(this.backBuffer, 0, 0); + } + + var doDrawOverlay = false; + + with (this.overlayBuffer.getContext("2d")) { + clearRect(0, 0, this.overlayBuffer.width, this.overlayBuffer.height); + if (this.selectionCursorTime || (this.selectionStartTime && this.selectionEndTime)) { + var spixel, epixel; + var pps = (this.frontBuffer.width / (this.endTime - this.startTime)); + + if (this.selectionCursorTime) { + spixel = Math.round((this.selectionCursorTime-this.startTime) * pps); + epixel = spixel + 1; + } else if (this.selectionStartTime && this.selectionEndTime) { + spixel = Math.round((this.selectionStartTime-this.startTime) * pps); + epixel = Math.round((this.selectionEndTime-this.startTime) * pps); + } + + globalCompositeOperation = "over"; + fillStyle = this.selectionColor; + fillRect(spixel, 0, epixel - spixel, this.frontBuffer.height); + + doDrawOverlay = true; + } + + if ((this.cursorType != "none") && this.cursorTime != null && this.cursorValue != null) { + globalCompositeOperation = "over"; + strokeStyle = this.cursorColor; + + var cw = this.frontBuffer.width; + var ch = this.frontBuffer.height; + + var v; + + v = ch - Math.round((this.cursorValue - this.yOffset) * this.yScale); + beginPath(); + moveTo( -0.5, v+0.5); + lineTo(cw+0.5, v+0.5); + stroke(); + + v = Math.round((this.cursorTime-this.startTime) * cw/(this.endTime - this.startTime)); + beginPath(); + moveTo(v+0.5, -0.5); + lineTo(v+0.5, ch+0.5); + stroke(); + + doDrawOverlay = true; + } + } + + if (doDrawOverlay) { + with (this.frontBuffer.getContext("2d")) { + globalCompositeOperation = "over"; + drawImage(this.overlayBuffer, 0, 0); + } + } + + }, + + + getValueAxisLabels: function () { + if (!this.dirty) + return this.yAxisLabels; + + // see getTimeAxisLabels for more commentary + + // y axis is either an arbitrary value or a percent + var visibleValues = this.frontBuffer.height * this.yScale; + var valuePerPixel = 1/this.yScale; + var labelValue = this.yLabelHeight * valuePerPixel; + + // round to nearest integer, but that's it; we can try to get + // fancy later on + var fixedPrecision; + if (this.hasRelative) { +/* + labelValue = 1; + + var vdiff = Math.ceil(this.dataSetMaxMaxVal) - Math.floor(this.dataSetMinMinVal); + if (vdiff <= 2) { + labelValue = .25; + } else if (vdiff <= 3) { + labelValue = .5; + } else { + labelValue = 1; + } +*/ + } else { + if (visibleValues > 1000) { + fixedPrecision = 0; + } else if (visibleValues > 100) { + fixedPrecision = 1; + } else if (visibleValues > 10) { + fixedPrecision = 2; + } else if (visibleValues > 1) { + fixedPrecision = 3; + } + } + + var numLabels = this.frontBuffer.height / this.yLabelHeight; + var labels = []; + var firstLabelOffsetValue = (labelValue - (this.yOffset % labelValue)); + + var visibleYMax = this.yOffset + this.frontBuffer.height/this.yScale; + + //log("yoffset", this.yOffset, "ymax", visibleYMax, "labelValue", labelValue, "numLabels", numLabels, "flo", firstLabelOffsetValue); + for (var i = 0; i < numLabels; i++) { + // figure out the time value of this label + var lvalue = this.yOffset + firstLabelOffsetValue + i*labelValue; + if (lvalue > visibleYMax) + break; + + // we want the text to correspond to the value drawn at the start of the block + // also note that Y axis is inverted + // XXX put back the -y/2 once we figure out how to vertically center a label's text + var lpos = this.frontBuffer.height - ((lvalue - this.yOffset)/valuePerPixel /* - (this.yLabelHeight/2)*/); + var l; + //log ("lpos: ", lpos, "lvalue", lvalue, "ysc", this.yScale); + if (this.hasRelative) { + l = [lpos, lvalue, (lvalue * 100).toFixed(0).toString() + "%"]; + } else { + l = [lpos, lvalue, lvalue.toFixed(fixedPrecision).toString()]; + } + //log("lval", lvalue, "lpos", l[0]); + labels.push(l); + } + + this.yAxisLabels = labels; + return labels; + }, + + getTimeAxisLabels: function () { + if (!this.dirty) + return this.xAxisLabels; + + // x axis is always time in seconds + + // duration is in seconds + var duration = this.endTime - this.startTime; + + // we know the pixel size and we know the time, we can + // compute the seconds per pixel + var secondsPerPixel = duration / this.frontBuffer.width; + + // so what's the exact duration of one label of our desired size? + var labelDuration = this.xLabelWidth * secondsPerPixel; + + // let's come up with a more round duration for our label. + if (labelDuration <= 60) { + labelDuration = 60; + } else if (labelDuration <= 14*60) { + labelDuration = Math.ceil(labelDuration / 60) * 60; + } else if (labelDuration <= 15*60) { + labelDuration = 15*60; + } else if (labelDuration <= 59*60) { + labelDuration = Math.ceil(labelDuration / (5*60)) * (5*60); + } else if (labelDuration <= 23*ONE_HOUR_SECONDS) { + labelDuration = Math.ceil(labelDuration / ONE_HOUR_SECONDS) * ONE_HOUR_SECONDS; + } else if (labelDuration <= 6*ONE_DAY_SECONDS) { + labelDuration = Math.ceil(labelDuration / ONE_DAY_SECONDS) * ONE_DAY_SECONDS; + } else { + // round to the nearest day at least + labelDuration = labelDuration - (labelDuration%ONE_DAY_SECONDS); + } + + // how many labels max can we fit? + var numLabels = (this.frontBuffer.width / this.xLabelWidth); + + var labels = []; + + // we want our first label to land on a multiple of the label duration; + // figure out where that lies. + var firstLabelOffsetSeconds = (labelDuration - (this.startTime % labelDuration)); + + //log ("sps", secondsPerPixel, "ldur", labelDuration, "nl", numLabels, "flo", firstLabelOffsetSeconds); + + for (var i = 0; i < numLabels; i++) { + // figure out the time value of this label + var ltime = this.startTime + firstLabelOffsetSeconds + i*labelDuration; + if (ltime > this.endTime) + break; + + // the first number is at what px position to place the label; + // the second number is the actual value of the label + // the third is an array of strings that go into the label + var lval = [(ltime - this.startTime)/secondsPerPixel - (this.xLabelWidth/2), ltime, this.formatTimeLabel(ltime)]; + //log ("ltime", ltime, "lpos", lval[0], "end", this.endTime); + labels.push(lval); + } + + this.xAxisLabels = labels; + return labels; + }, + + formatTimeLabel: function (ltime) { + // ltime is in seconds since the epoch in, um, so + var d = new Date (ltime*1000); + var s1 = d.getHours() + + (d.getMinutes() < 10 ? ":0" : ":") + d.getMinutes() + + (d.getSeconds() < 10 ? ":0" : ":") + d.getSeconds(); + var s2 = d.getDate() + " " + MONTH_ABBREV[d.getMonth()] + " " + (d.getYear()+1900); + return [s1, s2]; + }, + + makeLabels: function () { + //log ("makeLabels"); + if (this.xLabelContainer) { + var labels = []; + var xboxPos = YAHOO.util.Dom.getXY(this.xLabelContainer); + xboxPos[0] = xboxPos[0] + this.borderLeft; + xboxPos[1] = xboxPos[1] + this.borderTop; + var labelValues = this.getTimeAxisLabels(); + + for each (var lval in labelValues) { + var xpos = /*xboxPos[0] +*/ lval[0]; + var div = new DIV({ class: "x-axis-label" }); + div.style.position = "absolute"; + div.style.width = this.xLabelWidth + "px"; + div.style.height = this.xLabelHeight + "px"; + div.style.left = xpos + "px"; + div.style.top = "0px"; //xboxPos[1] + this.frontBuffer.height; + + // XXX don't hardcode [2][0] etc. + appendChildNodes(div, lval[2][0], new BR(), lval[2][1]); + + labels.push(div); + } + + replaceChildNodes(this.xLabelContainer, labels); + } + + if (this.yLabelContainer) { + var labels = []; + var yboxPos = YAHOO.util.Dom.getXY(this.yLabelContainer); + yboxPos[0] = yboxPos[0] + this.borderLeft; + yboxPos[1] = yboxPos[1] + this.borderTop; + var labelValues = this.getValueAxisLabels(); + + for each (var lval in labelValues) { + var ypos = /*xboxPos[0] +*/ lval[0]; + var div = new DIV({ class: "y-axis-label" }); + div.style.position = "absolute"; + div.style.width = this.yLabelWidth + "px"; + div.style.height = this.yLabelHeight + "px"; + div.style.left = "0px"; //xboxPos[0] + // XXX remove the -5 once we figure out how to vertically center text in this box + div.style.top = (ypos-8) + "px"; + + // XXX don't hardcode [2] etc. + appendChildNodes(div, lval[2]); + labels.push(div); + } + + replaceChildNodes(this.yLabelContainer, labels); + } + + if (0) { + var labels = []; + var total_sz = this.frontBuffer.height; + + // the ideal label height is 30px; 10% extra for gaps + var sz_desired = 30; + var nlabels = Math.floor(total_sz / (sz_desired * 1.10)); + var label_sz = Math.floor(total_sz / nlabels); + + //log ("lsz: " + label_sz + " nl: " + nlabels); + + for (var i = 0; i < nlabels; i++) { + var pos = label_sz * i; + var div = new DIV({class: "y-axis-label", style: "width: 50px; height: " + label_sz + "px" }); + appendChildNodes(div, "Label " + i); + + labels.push(div); + } + + replaceChildNodes(this.yLabelContainer, labels); + } + }, + + // + // selection handling + // + selectionMouseDown: function(event) { + if (!this.valid) + return; + + if (this.selectionType == "range") { + var pos = YAHOO.util.Dom.getX(this.frontBuffer) + this.borderLeft; + this.dragState = { startX: event.pageX - pos }; + var ds = this.dragState; + + ds.curX = ds.startX + 1; + ds.secondsPerPixel = (this.endTime - this.startTime) / this.frontBuffer.width; + + this.selectionStartTime = ds.startX * ds.secondsPerPixel + this.startTime; + this.selectionEndTime = ds.curX * ds.secondsPerPixel + this.startTime; + + this.redrawOverlayOnly(); + + this.selectionSweeping = true; + } else if (this.selectionType == "cursor") { + var pos = YAHOO.util.Dom.getX(this.frontBuffer) + this.borderLeft; + var secondsPerPixel = (this.endTime - this.startTime) / this.frontBuffer.width; + + this.selectionCursorTime = (event.pageX - pos) * secondsPerPixel + this.startTime; + + this.redrawOverlayOnly(); + + this.onSelectionChanged.fire("cursor", this.selectionCursorTime); + } + }, + + abortSelection: function() { + if (!this.selectionSweeping) + return; + + this.selectionSweeping = false; + this.redrawOverlayOnly(); + }, + + clearSelection: function() { + this.selectionSweeping = false; + this.selectionStartTime = null; + this.selectionEndTime = null; + this.redrawOverlayOnly(); + }, + + selectionUpdateFromEventPageCoordinate: function(pagex) { + var pos = YAHOO.util.Dom.getX(this.frontBuffer) + this.borderLeft; + var ds = this.dragState; + ds.curX = pagex - pos; + if (ds.curX > this.frontBuffer.width) + ds.curX = this.frontBuffer.width; + else if (ds.curX < 0) + ds.curX = 0; + + var cxTime = (ds.curX * ds.secondsPerPixel) + this.startTime; + var startxTime = (ds.startX * ds.secondsPerPixel) + this.startTime; + if (ds.curX < ds.startX) { + this.selectionEndTime = startxTime; + this.selectionStartTime = cxTime; + } else { + this.selectionStartTime = startxTime; + this.selectionEndTime = cxTime; + } + }, + + selectionMouseMove: function(event) { + if (!this.selectionSweeping) + return; + + this.selectionUpdateFromEventPageCoordinate(event.pageX); + + this.redrawOverlayOnly(); + }, + + selectionMouseUp: function(event) { + if (!this.selectionSweeping) + return; + + this.selectionSweeping = false; + this.onSelectionChanged.fire("range", this.selectionStartTime, this.selectionEndTime); + }, + + selectionMouseOut: function(event) { + if (!this.selectionSweeping) + return; + + this.selectionUpdateFromEventPageCoordinate(event.pageX); + + this.selectionSweeping = false; + this.onSelectionChanged.fire("range", this.selectionStartTime, this.selectionEndTime); + }, + + /* + * cursor stuff + */ + cursorMouseMove: function (event) { + if (!this.valid) + return; + + if (this.cursorType != "free") + return; + + var pos = YAHOO.util.Dom.getXY(this.frontBuffer); + pos[0] = pos[0] + this.borderLeft; + pos[1] = pos[1] + this.borderTop; + var secondsPerPixel = (this.endTime - this.startTime) / this.frontBuffer.width; + var valuesPerPixel = 1.0 / this.yScale; + + this.cursorTime = (event.pageX - pos[0]) * secondsPerPixel + this.startTime; + this.cursorValue = (this.frontBuffer.height - (event.pageY - pos[1])) * valuesPerPixel + this.yOffset; + + this.onCursorMoved.fire(this.cursorTime, this.cursorValue); + + this.redrawOverlayOnly(); + }, + + cursorMouseOut: function (event) { + if (!this.valid) + return; + + if (this.cursorType != "free") + return; + + this.cursorTime = null; + this.cursorValue = null; + + this.onCursorMoved.fire(this.cursorTime, this.cursorValue); + + this.redrawOverlayOnly(); + }, +}; + +function BigGraph(canvasId) { + this.__proto__.__proto__.init.call (this, canvasId); +} + +BigGraph.prototype = { + __proto__: new Graph(), + +}; + +function SmallGraph(canvasId) { + this.__proto__.__proto__.init.call (this, canvasId); +} + +SmallGraph.prototype = { + __proto__: new Graph(), + + yLabelHeight: 20, +}; + +var GraphFormModules = []; +var GraphFormModuleCount = 0; + +function GraphFormModule(userConfig) { + GraphFormModuleCount++; + this.__proto__.__proto__.constructor.call(this, "graphForm" + GraphFormModuleCount, userConfig); +} + +GraphFormModule.prototype = { + __proto__: new YAHOO.widget.Module(), + + imageRoot: "", + + tinderbox: null, + testname: null, + baseline: false, + average: false, + + init: function (el, userConfig) { + var self = this; + + this.__proto__.__proto__.init.call(this, el/*, userConfig*/); + + this.cfg = new YAHOO.util.Config(this); + this.cfg.addProperty("tinderbox", { suppressEvent: true }); + this.cfg.addProperty("testname", { suppressEvent: true }); + this.cfg.addProperty("baseline", { suppressEvent: true }); + + if (userConfig) + this.cfg.applyConfig(userConfig, true); + + //form = new FORM({ class: "graphform", action: "javascript:;"}); + form = new DIV({ class: "graphform-line" }); + el = new SPAN({ class: "graphform-first-span" }); + form.appendChild(el); + + el = new SELECT({ name: "testname", + class: "testname", + onchange: function(event) { self.onChangeTestname(); } }); + this.testSelect = el; + form.appendChild(el); + + appendChildNodes(form, " on "); + + el = new SELECT({ name: "tinderbox", + class: "tinderbox", + onchange: function(event) { self.onChangeTinderbox(); } }); + this.tinderboxSelect = el; + form.appendChild(el); + + appendChildNodes(form, " (average: "); + el = new INPUT({ name: "average", + type: "checkbox", + onchange: function(event) { self.average = event.target.checked; } }); + this.averageCheckbox = el; + form.appendChild(el); + appendChildNodes(form, ")"); + + this.colorDiv = new IMG({ style: "border: 1px solid black; vertical-align: middle; margin: 3px;", + width: 15, + height: 15, + src: "js/img/clear.png" }); + form.appendChild(this.colorDiv); + + el = new IMG({ src: "js/img/plus.png", class: "plusminus", + onclick: function(event) { addGraphForm(); } }); + form.appendChild(el); + el = new IMG({ src: "js/img/minus.png", class: "plusminus", + onclick: function(event) { self.remove(); } }); + form.appendChild(el); +/* + el = new INPUT({ type: "radio", + name: "baseline", + onclick: function(event) { self.onBaseLineRadioClick(); } }); + form.appendChild(el); +*/ + + + this.setBody (form); + + var forceTinderbox = null, forceTestname = null; + if (userConfig) { + forceTinderbox = this.cfg.getProperty("tinderbox"); + forceTestname = this.cfg.getProperty("testname"); + baseline = this.cfg.getProperty("baseline"); + if (baseline) + this.onBaseLineRadioClick(); + } + + Tinderbox.requestTinderboxList(function (tboxes) { + var opts = []; + for each (var tbox in tboxes) { + opts.push(new OPTION({ value: tbox }, tbox)); + } + replaceChildNodes(self.tinderboxSelect, opts); + + if (forceTinderbox != null) + self.tinderboxSelect.value = forceTinderbox; + + setTimeout(function () { self.onChangeTinderbox(forceTestname); }, 0); + }); + + GraphFormModules.push(this); + }, + + getQueryString: function (prefix) { + return prefix + "tb=" + this.tinderbox + "&" + prefix + "tn=" + this.testname + "&" + prefix + "bl=" + (this.baseline ? "1" : "0"); + }, + +/* + handleQueryStringData: function (prefix, qsdata) { + var tbox = qsdata[prefix + "tb"]; + var tname = qsdata[prefix + "tn"]; + var baseline = (qsdata[prefix + "bl"] == "1"); + + if (baseline) + this.onBaseLineRadioClick(); + + this.forcedTinderbox = tbox; + this.tinderboxSelect.value = tbox; + + this.forcedTestname = tname; + this.testSelect.value = tname; + this.onChangeTinderbox(); + }, +*/ + + onChangeTinderbox: function (forceTestname) { + var self = this; + + this.tinderbox = this.tinderboxSelect.value; + + Tinderbox.requestTestListFor(this.tinderbox, + function (tbox, tests) { + var opts = []; + for each (var test in tests) { + opts.push(new OPTION({ value: test }, test)); + } + + self.testname = tests[0]; + replaceChildNodes(self.testSelect, opts); + + if (forceTestname) { + self.testname = forceTestname; + self.testSelect.value = forceTestname; + } + }); + }, + + onChangeTestname: function () { + var self = this; + + this.testname = this.testSelect.value; + }, + + onBaseLineRadioClick: function () { + GraphFormModules.forEach(function (g) { g.baseline = false; }); + this.baseline = true; + }, + + remove: function () { + var nf = []; + for each (var f in GraphFormModules) { + if (f != this) + nf.push(f); + } + GraphFormModules = nf; + this.destroy(); + }, +}; + +var Tinderbox; +var BigPerfGraph; +var SmallPerfGraph; + +function loadingDone() { + //createLoggingPane(true); + + Tinderbox = new TinderboxData(); + Tinderbox.init(); + + SmallPerfGraph = new SmallGraph("smallgraph"); + SmallPerfGraph.setSelectionType("range"); + BigPerfGraph = new BigGraph("graph"); + BigPerfGraph.setSelectionType("cursor"); + BigPerfGraph.setCursorType("free"); + + onDataLoadChanged(); + + SmallPerfGraph.onSelectionChanged.subscribe (function (type, args, obj) { + log ("selchanged"); + if (args[0] == "range") { + BigPerfGraph.setTimeRange (args[1], args[2]); + BigPerfGraph.autoScale(); + BigPerfGraph.redraw(); + } + + updateLinkToThis(); + }); + + BigPerfGraph.onCursorMoved.subscribe (function (type, args, obj) { + var time = args[0]; + var val = args[1]; + if (time != null && val != null) { + // cheat + var l = Graph.prototype.formatTimeLabel (time); + showStatus("Date: " + l[1] + " " + l[0] + " Value: " + val.toFixed(2)); + } else { + showStatus(null); + } + }); + if (document.location.hash) { + handleHash(document.location.hash); + } else { + addGraphForm(); + } +} + +function addGraphForm(config) { + var m = new GraphFormModule(config); + m.render (getElement("graphforms")); + return m; +} + +function onNoBaseLineClick() { + GraphFormModules.forEach (function (g) { g.baseline = false; }); +} + +function onGraph() { + for each (var g in [BigPerfGraph, SmallPerfGraph]) { + g.clearDataSets(); + g.setTimeRange(null, null); + } + + var baselineModule = null; + GraphFormModules.forEach (function (g) { if (g.baseline) baselineModule = g; }); + if (baselineModule) { + baselineModule.colorDiv.style.backgroundColor = "black"; + Tinderbox.requestValueDataSetFor (baselineModule.tinderbox, baselineModule.testname, + function (tbox, test, ds) { + try { + log ("Got results for baseline: '" + tbox + "' '" + test + "' ds: " + ds); + onGraphLoadRemainder(ds); + } catch(e) { log(e); } + }); + } else { + onGraphLoadRemainder(); + } +} + +function onGraphLoadRemainder(baselineDataSet) { + for each (var graphModule in GraphFormModules) { + // this would have been loaded earlier + if (graphModule.baseline) + continue; + + var autoExpand = true; + if (SmallPerfGraph.selectionType == "range" && + SmallPerfGraph.selectionStartTime && + SmallPerfGraph.selectionEndTime) + { + BigPerfGraph.setTimeRange (SmallPerfGraph.selectionStartTime, SmallPerfGraph.selectionEndTime); + autoExpand = false; + } + + Tinderbox.requestValueDataSetFor (graphModule.tinderbox, graphModule.testname, + function (tbox, test, ds) { + try { + if (baselineDataSet) + ds = ds.createRelativeTo(baselineDataSet); + + var gm = findGraphModule(tbox, test); + if (gm) + gm.colorDiv.style.backgroundColor = ds.color; + + log ("got ds:", ds.firstTime, ds.lastTime, ds.data.length); + var avgds = null; + if (baselineDataSet == null && + graphModule.average) + { + avgds = ds.createAverage(gAverageInterval); + } + + if (avgds) + log ("got avgds:", avgds.firstTime, avgds.lastTime, avgds.data.length); + + + for each (g in [BigPerfGraph, SmallPerfGraph]) { + g.addDataSet(ds); + if (avgds) + g.addDataSet(avgds); + if (g == SmallPerfGraph || autoExpand) + g.expandTimeRange(ds.firstTime, ds.lastTime); + g.autoScale(); + g.redraw(); + } + + updateLinkToThis(); + + } catch(e) { log(e); } + }); + } +} + +function onDataLoadChanged() { + log ("loadchanged"); + if (getElement("load-days-radio").checked) { + var dval = new Number(getElement("load-days-entry").value); + log ("dval", dval); + if (dval <= 0) { + //getElement("load-days-entry").style.background-color = "red"; + return; + } else { + //getElement("load-days-entry").style.background-color = "inherit"; + } + + var d2 = Math.ceil(Date.now() / 1000); + d2 = (d2 - (d2 % ONE_DAY_SECONDS)) + ONE_DAY_SECONDS; + var d1 = Math.floor(d2 - (dval * ONE_DAY_SECONDS)); + log ("drange", d1, d2); + + Tinderbox.defaultLoadRange = [d1, d2]; + } else { + Tinderbox.defaultLoadRange = null; + } + + Tinderbox.clearValueDataSets(); + + // hack, reset colors + randomColorBias = 0; +} + +function findGraphModule(tbox, test) { + for each (var gm in GraphFormModules) { + if (gm.tinderbox == tbox && gm.testname == test) + return gm; + } + return null; +} + +function updateLinkToThis() { + var qs = ""; + + qs += SmallPerfGraph.getQueryString("sp"); + qs += "&"; + qs += BigPerfGraph.getQueryString("bp"); + + var ctr = 1; + for each (var gm in GraphFormModules) { + qs += "&" + gm.getQueryString("m" + ctr); + ctr++; + } + + getElement("linktothis").href = document.location.pathname + "#" + qs; +} + +function handleHash(hash) { + var qsdata = {}; + for each (var s in hash.substring(1).split("&")) { + var q = s.split("="); + qsdata[q[0]] = q[1]; + } + + var ctr = 1; + while (("m" + ctr + "tb") in qsdata) { + var prefix = "m" + ctr; + var tbox = qsdata[prefix + "tb"]; + var tname = qsdata[prefix + "tn"]; + var baseline = (qsdata[prefix + "bl"] == "1"); + + // passing this is pretty stupid here + + var m = addGraphForm({tinderbox: tbox, testname: tname, baseline: baseline}); + //m.handleQueryStringData("m" + ctr, qsdata); + + ctr++; + } + + SmallPerfGraph.handleQueryStringData("sp", qsdata); + BigPerfGraph.handleQueryStringData("bp", qsdata); +} + +function showStatus(s) { + replaceChildNodes("status", s); +} + +/* Get some pre-set colors in for the first 5 graphs, thens start randomly generating stuff */ +var presetColorIndex = 0; +var presetColors = [ + [0.0, 0.0, 0.7, 1.0], + [0.0, 0.5, 0.0, 1.0], + [0.7, 0.0, 0.0, 1.0], + [0.7, 0.0, 0.7, 1.0], + [0.0, 0.7, 0.7, 1.0] +]; + +var randomColorBias = 0; +function randomColor() { + if (presetColorIndex < presetColors.length) { + return presetColors[presetColorIndex++]; + } + + var col = [ + (Math.random()*0.5) + ((randomColorBias==0) ? 0.5 : 0.2), + (Math.random()*0.5) + ((randomColorBias==1) ? 0.5 : 0.2), + (Math.random()*0.5) + ((randomColorBias==2) ? 0.5 : 0.2), + 1.0 + ]; + randomColorBias++; + if (randomColorBias == 3) + randomColorBias = 0; + + return col; +} + +function lighterColor(col) { + return [ + Math.min(0.85, col[0] * 1.2), + Math.min(0.85, col[1] * 1.2), + Math.min(0.85, col[2] * 1.2), + col[3] + ]; +} + +function colorToRgbString(col) { + return "rgba(" + + Math.floor(col[0]*255) + "," + + Math.floor(col[1]*255) + "," + + Math.floor(col[2]*255) + "," + + col[3] + + ")"; +} diff --git a/webtools/new-graph/js/img/clear.png b/webtools/new-graph/js/img/clear.png new file mode 100644 index 00000000000..0d65aa65603 Binary files /dev/null and b/webtools/new-graph/js/img/clear.png differ diff --git a/webtools/new-graph/js/img/minus.png b/webtools/new-graph/js/img/minus.png new file mode 100644 index 00000000000..6e2dde8d756 Binary files /dev/null and b/webtools/new-graph/js/img/minus.png differ diff --git a/webtools/new-graph/js/img/plus.png b/webtools/new-graph/js/img/plus.png new file mode 100644 index 00000000000..7ce9d6fa307 Binary files /dev/null and b/webtools/new-graph/js/img/plus.png differ diff --git a/webtools/new-graph/js/mochikit/Async.js b/webtools/new-graph/js/mochikit/Async.js new file mode 100644 index 00000000000..1f274d07c13 --- /dev/null +++ b/webtools/new-graph/js/mochikit/Async.js @@ -0,0 +1,637 @@ +/*** + +MochiKit.Async 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide("MochiKit.Async"); + dojo.require("MochiKit.Base"); +} +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Base", []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.Async depends on MochiKit.Base!"; +} + +if (typeof(MochiKit.Async) == 'undefined') { + MochiKit.Async = {}; +} + +MochiKit.Async.NAME = "MochiKit.Async"; +MochiKit.Async.VERSION = "1.3.1"; +MochiKit.Async.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; +MochiKit.Async.toString = function () { + return this.__repr__(); +}; + +MochiKit.Async.Deferred = function (/* optional */ canceller) { + this.chain = []; + this.id = this._nextId(); + this.fired = -1; + this.paused = 0; + this.results = [null, null]; + this.canceller = canceller; + this.silentlyCancelled = false; + this.chained = false; +}; + +MochiKit.Async.Deferred.prototype = { + repr: function () { + var state; + if (this.fired == -1) { + state = 'unfired'; + } else if (this.fired === 0) { + state = 'success'; + } else { + state = 'error'; + } + return 'Deferred(' + this.id + ', ' + state + ')'; + }, + + toString: MochiKit.Base.forwardCall("repr"), + + _nextId: MochiKit.Base.counter(), + + cancel: function () { + var self = MochiKit.Async; + if (this.fired == -1) { + if (this.canceller) { + this.canceller(this); + } else { + this.silentlyCancelled = true; + } + if (this.fired == -1) { + this.errback(new self.CancelledError(this)); + } + } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) { + this.results[0].cancel(); + } + }, + + + _pause: function () { + /*** + + Used internally to signal that it's waiting on another Deferred + + ***/ + this.paused++; + }, + + _unpause: function () { + /*** + + Used internally to signal that it's no longer waiting on another + Deferred. + + ***/ + this.paused--; + if ((this.paused === 0) && (this.fired >= 0)) { + this._fire(); + } + }, + + _continue: function (res) { + /*** + + Used internally when a dependent deferred fires. + + ***/ + this._resback(res); + this._unpause(); + }, + + _resback: function (res) { + /*** + + The primitive that means either callback or errback + + ***/ + this.fired = ((res instanceof Error) ? 1 : 0); + this.results[this.fired] = res; + this._fire(); + }, + + _check: function () { + if (this.fired != -1) { + if (!this.silentlyCancelled) { + throw new MochiKit.Async.AlreadyCalledError(this); + } + this.silentlyCancelled = false; + return; + } + }, + + callback: function (res) { + this._check(); + if (res instanceof MochiKit.Async.Deferred) { + throw new Error("Deferred instances can only be chained if they are the result of a callback"); + } + this._resback(res); + }, + + errback: function (res) { + this._check(); + var self = MochiKit.Async; + if (res instanceof self.Deferred) { + throw new Error("Deferred instances can only be chained if they are the result of a callback"); + } + if (!(res instanceof Error)) { + res = new self.GenericError(res); + } + this._resback(res); + }, + + addBoth: function (fn) { + if (arguments.length > 1) { + fn = MochiKit.Base.partial.apply(null, arguments); + } + return this.addCallbacks(fn, fn); + }, + + addCallback: function (fn) { + if (arguments.length > 1) { + fn = MochiKit.Base.partial.apply(null, arguments); + } + return this.addCallbacks(fn, null); + }, + + addErrback: function (fn) { + if (arguments.length > 1) { + fn = MochiKit.Base.partial.apply(null, arguments); + } + return this.addCallbacks(null, fn); + }, + + addCallbacks: function (cb, eb) { + if (this.chained) { + throw new Error("Chained Deferreds can not be re-used"); + } + this.chain.push([cb, eb]); + if (this.fired >= 0) { + this._fire(); + } + return this; + }, + + _fire: function () { + /*** + + Used internally to exhaust the callback sequence when a result + is available. + + ***/ + var chain = this.chain; + var fired = this.fired; + var res = this.results[fired]; + var self = this; + var cb = null; + while (chain.length > 0 && this.paused === 0) { + // Array + var pair = chain.shift(); + var f = pair[fired]; + if (f === null) { + continue; + } + try { + res = f(res); + fired = ((res instanceof Error) ? 1 : 0); + if (res instanceof MochiKit.Async.Deferred) { + cb = function (res) { + self._continue(res); + }; + this._pause(); + } + } catch (err) { + fired = 1; + if (!(err instanceof Error)) { + err = new MochiKit.Async.GenericError(err); + } + res = err; + } + } + this.fired = fired; + this.results[fired] = res; + if (cb && this.paused) { + // this is for "tail recursion" in case the dependent deferred + // is already fired + res.addBoth(cb); + res.chained = true; + } + } +}; + +MochiKit.Base.update(MochiKit.Async, { + evalJSONRequest: function (/* req */) { + return eval('(' + arguments[0].responseText + ')'); + }, + + succeed: function (/* optional */result) { + var d = new MochiKit.Async.Deferred(); + d.callback.apply(d, arguments); + return d; + }, + + fail: function (/* optional */result) { + var d = new MochiKit.Async.Deferred(); + d.errback.apply(d, arguments); + return d; + }, + + getXMLHttpRequest: function () { + var self = arguments.callee; + if (!self.XMLHttpRequest) { + var tryThese = [ + function () { return new XMLHttpRequest(); }, + function () { return new ActiveXObject('Msxml2.XMLHTTP'); }, + function () { return new ActiveXObject('Microsoft.XMLHTTP'); }, + function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); }, + function () { + throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest"); + } + ]; + for (var i = 0; i < tryThese.length; i++) { + var func = tryThese[i]; + try { + self.XMLHttpRequest = func; + return func(); + } catch (e) { + // pass + } + } + } + return self.XMLHttpRequest(); + }, + + _nothing: function () {}, + + _xhr_onreadystatechange: function (d) { + // MochiKit.Logging.logDebug('this.readyState', this.readyState); + if (this.readyState == 4) { + // IE SUCKS + try { + this.onreadystatechange = null; + } catch (e) { + try { + this.onreadystatechange = MochiKit.Async._nothing; + } catch (e) { + } + } + var status = null; + try { + status = this.status; + if (!status && MochiKit.Base.isNotEmpty(this.responseText)) { + // 0 or undefined seems to mean cached or local + status = 304; + } + } catch (e) { + // pass + // MochiKit.Logging.logDebug('error getting status?', repr(items(e))); + } + // 200 is OK, 304 is NOT_MODIFIED + if (status == 200 || status == 304) { // OK + d.callback(this); + } else { + var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed"); + if (err.number) { + // XXX: This seems to happen on page change + d.errback(err); + } else { + // XXX: this seems to happen when the server is unreachable + d.errback(err); + } + } + } + }, + + _xhr_canceller: function (req) { + // IE SUCKS + try { + req.onreadystatechange = null; + } catch (e) { + try { + req.onreadystatechange = MochiKit.Async._nothing; + } catch (e) { + } + } + req.abort(); + }, + + + sendXMLHttpRequest: function (req, /* optional */ sendContent) { + if (typeof(sendContent) == "undefined" || sendContent === null) { + sendContent = ""; + } + + var m = MochiKit.Base; + var self = MochiKit.Async; + var d = new self.Deferred(m.partial(self._xhr_canceller, req)); + + try { + req.onreadystatechange = m.bind(self._xhr_onreadystatechange, + req, d); + req.send(sendContent); + } catch (e) { + try { + req.onreadystatechange = null; + } catch (ignore) { + // pass + } + d.errback(e); + } + + return d; + + }, + + doSimpleXMLHttpRequest: function (url/*, ...*/) { + var self = MochiKit.Async; + var req = self.getXMLHttpRequest(); + if (arguments.length > 1) { + var m = MochiKit.Base; + var qs = m.queryString.apply(null, m.extend(null, arguments, 1)); + if (qs) { + url += "?" + qs; + } + } + req.open("GET", url, true); + return self.sendXMLHttpRequest(req); + }, + + loadJSONDoc: function (url) { + var self = MochiKit.Async; + var d = self.doSimpleXMLHttpRequest.apply(self, arguments); + d = d.addCallback(self.evalJSONRequest); + return d; + }, + + wait: function (seconds, /* optional */value) { + var d = new MochiKit.Async.Deferred(); + var m = MochiKit.Base; + if (typeof(value) != 'undefined') { + d.addCallback(function () { return value; }); + } + var timeout = setTimeout( + m.bind("callback", d), + Math.floor(seconds * 1000)); + d.canceller = function () { + try { + clearTimeout(timeout); + } catch (e) { + // pass + } + }; + return d; + }, + + callLater: function (seconds, func) { + var m = MochiKit.Base; + var pfunc = m.partial.apply(m, m.extend(null, arguments, 1)); + return MochiKit.Async.wait(seconds).addCallback( + function (res) { return pfunc(); } + ); + } +}); + + +MochiKit.Async.DeferredLock = function () { + this.waiting = []; + this.locked = false; + this.id = this._nextId(); +}; + +MochiKit.Async.DeferredLock.prototype = { + __class__: MochiKit.Async.DeferredLock, + acquire: function () { + d = new MochiKit.Async.Deferred(); + if (this.locked) { + this.waiting.push(d); + } else { + this.locked = true; + d.callback(this); + } + return d; + }, + release: function () { + if (!this.locked) { + throw TypeError("Tried to release an unlocked DeferredLock"); + } + this.locked = false; + if (this.waiting.length > 0) { + this.locked = true; + this.waiting.shift().callback(this); + } + }, + _nextId: MochiKit.Base.counter(), + repr: function () { + var state; + if (this.locked) { + state = 'locked, ' + this.waiting.length + ' waiting'; + } else { + state = 'unlocked'; + } + return 'DeferredLock(' + this.id + ', ' + state + ')'; + }, + toString: MochiKit.Base.forwardCall("repr") + +}; + +MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller) { + this.list = list; + this.resultList = new Array(this.list.length); + + // Deferred init + this.chain = []; + this.id = this._nextId(); + this.fired = -1; + this.paused = 0; + this.results = [null, null]; + this.canceller = canceller; + this.silentlyCancelled = false; + + if (this.list.length === 0 && !fireOnOneCallback) { + this.callback(this.resultList); + } + + this.finishedCount = 0; + this.fireOnOneCallback = fireOnOneCallback; + this.fireOnOneErrback = fireOnOneErrback; + this.consumeErrors = consumeErrors; + + var index = 0; + MochiKit.Base.map(MochiKit.Base.bind(function (d) { + d.addCallback(MochiKit.Base.bind(this._cbDeferred, this), index, true); + d.addErrback(MochiKit.Base.bind(this._cbDeferred, this), index, false); + index += 1; + }, this), this.list); +}; + +MochiKit.Base.update(MochiKit.Async.DeferredList.prototype, + MochiKit.Async.Deferred.prototype); + +MochiKit.Base.update(MochiKit.Async.DeferredList.prototype, { + _cbDeferred: function (index, succeeded, result) { + this.resultList[index] = [succeeded, result]; + this.finishedCount += 1; + if (this.fired !== 0) { + if (succeeded && this.fireOnOneCallback) { + this.callback([index, result]); + } else if (!succeeded && this.fireOnOneErrback) { + this.errback(result); + } else if (this.finishedCount == this.list.length) { + this.callback(this.resultList); + } + } + if (!succeeded && this.consumeErrors) { + result = null; + } + return result; + } +}); + +MochiKit.Async.gatherResults = function (deferredList) { + var d = new MochiKit.Async.DeferredList(deferredList, false, true, false); + d.addCallback(function (results) { + var ret = []; + for (var i = 0; i < results.length; i++) { + ret.push(results[i][1]); + } + return ret; + }); + return d; +}; + +MochiKit.Async.maybeDeferred = function (func) { + var self = MochiKit.Async; + var result; + try { + var r = func.apply(null, MochiKit.Base.extend([], arguments, 1)); + if (r instanceof self.Deferred) { + result = r; + } else if (r instanceof Error) { + result = self.fail(r); + } else { + result = self.succeed(r); + } + } catch (e) { + result = self.fail(e); + } + return result; +}; + + +MochiKit.Async.EXPORT = [ + "AlreadyCalledError", + "CancelledError", + "BrowserComplianceError", + "GenericError", + "XMLHttpRequestError", + "Deferred", + "succeed", + "fail", + "getXMLHttpRequest", + "doSimpleXMLHttpRequest", + "loadJSONDoc", + "wait", + "callLater", + "sendXMLHttpRequest", + "DeferredLock", + "DeferredList", + "gatherResults", + "maybeDeferred" +]; + +MochiKit.Async.EXPORT_OK = [ + "evalJSONRequest" +]; + +MochiKit.Async.__new__ = function () { + var m = MochiKit.Base; + var ne = m.partial(m._newNamedError, this); + ne("AlreadyCalledError", + function (deferred) { + /*** + + Raised by the Deferred if callback or errback happens + after it was already fired. + + ***/ + this.deferred = deferred; + } + ); + + ne("CancelledError", + function (deferred) { + /*** + + Raised by the Deferred cancellation mechanism. + + ***/ + this.deferred = deferred; + } + ); + + ne("BrowserComplianceError", + function (msg) { + /*** + + Raised when the JavaScript runtime is not capable of performing + the given function. Technically, this should really never be + raised because a non-conforming JavaScript runtime probably + isn't going to support exceptions in the first place. + + ***/ + this.message = msg; + } + ); + + ne("GenericError", + function (msg) { + this.message = msg; + } + ); + + ne("XMLHttpRequestError", + function (req, msg) { + /*** + + Raised when an XMLHttpRequest does not complete for any reason. + + ***/ + this.req = req; + this.message = msg; + try { + // Strange but true that this can raise in some cases. + this.number = req.status; + } catch (e) { + // pass + } + } + ); + + + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": m.concat(this.EXPORT, this.EXPORT_OK) + }; + + m.nameFunctions(this); + +}; + +MochiKit.Async.__new__(); + +MochiKit.Base._exportSymbols(this, MochiKit.Async); diff --git a/webtools/new-graph/js/mochikit/Base.js b/webtools/new-graph/js/mochikit/Base.js new file mode 100644 index 00000000000..62f50d89dc0 --- /dev/null +++ b/webtools/new-graph/js/mochikit/Base.js @@ -0,0 +1,1131 @@ +/*** + +MochiKit.Base 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide("MochiKit.Base"); +} + +if (typeof(MochiKit) == 'undefined') { + MochiKit = {}; +} +if (typeof(MochiKit.Base) == 'undefined') { + MochiKit.Base = {}; +} + +MochiKit.Base.VERSION = "1.3.1"; +MochiKit.Base.NAME = "MochiKit.Base"; +MochiKit.Base.update = function (self, obj/*, ... */) { + if (self === null) { + self = {}; + } + for (var i = 1; i < arguments.length; i++) { + var o = arguments[i]; + if (typeof(o) != 'undefined' && o !== null) { + for (var k in o) { + self[k] = o[k]; + } + } + } + return self; +}; + +MochiKit.Base.update(MochiKit.Base, { + __repr__: function () { + return "[" + this.NAME + " " + this.VERSION + "]"; + }, + + toString: function () { + return this.__repr__(); + }, + + counter: function (n/* = 1 */) { + if (arguments.length === 0) { + n = 1; + } + return function () { + return n++; + }; + }, + + clone: function (obj) { + var me = arguments.callee; + if (arguments.length == 1) { + me.prototype = obj; + return new me(); + } + }, + + flattenArguments: function (lst/* ...*/) { + var res = []; + var m = MochiKit.Base; + var args = m.extend(null, arguments); + while (args.length) { + var o = args.shift(); + if (o && typeof(o) == "object" && typeof(o.length) == "number") { + for (var i = o.length - 1; i >= 0; i--) { + args.unshift(o[i]); + } + } else { + res.push(o); + } + } + return res; + }, + + extend: function (self, obj, /* optional */skip) { + // Extend an array with an array-like object starting + // from the skip index + if (!skip) { + skip = 0; + } + if (obj) { + // allow iterable fall-through, but skip the full isArrayLike + // check for speed, this is called often. + var l = obj.length; + if (typeof(l) != 'number' /* !isArrayLike(obj) */) { + if (typeof(MochiKit.Iter) != "undefined") { + obj = MochiKit.Iter.list(obj); + l = obj.length; + } else { + throw new TypeError("Argument not an array-like and MochiKit.Iter not present"); + } + } + if (!self) { + self = []; + } + for (var i = skip; i < l; i++) { + self.push(obj[i]); + } + } + // This mutates, but it's convenient to return because + // it's often used like a constructor when turning some + // ghetto array-like to a real array + return self; + }, + + + updatetree: function (self, obj/*, ...*/) { + if (self === null) { + self = {}; + } + for (var i = 1; i < arguments.length; i++) { + var o = arguments[i]; + if (typeof(o) != 'undefined' && o !== null) { + for (var k in o) { + var v = o[k]; + if (typeof(self[k]) == 'object' && typeof(v) == 'object') { + arguments.callee(self[k], v); + } else { + self[k] = v; + } + } + } + } + return self; + }, + + setdefault: function (self, obj/*, ...*/) { + if (self === null) { + self = {}; + } + for (var i = 1; i < arguments.length; i++) { + var o = arguments[i]; + for (var k in o) { + if (!(k in self)) { + self[k] = o[k]; + } + } + } + return self; + }, + + keys: function (obj) { + var rval = []; + for (var prop in obj) { + rval.push(prop); + } + return rval; + }, + + items: function (obj) { + var rval = []; + var e; + for (var prop in obj) { + var v; + try { + v = obj[prop]; + } catch (e) { + continue; + } + rval.push([prop, v]); + } + return rval; + }, + + + _newNamedError: function (module, name, func) { + func.prototype = new MochiKit.Base.NamedError(module.NAME + "." + name); + module[name] = func; + }, + + + operator: { + // unary logic operators + truth: function (a) { return !!a; }, + lognot: function (a) { return !a; }, + identity: function (a) { return a; }, + + // bitwise unary operators + not: function (a) { return ~a; }, + neg: function (a) { return -a; }, + + // binary operators + add: function (a, b) { return a + b; }, + sub: function (a, b) { return a - b; }, + div: function (a, b) { return a / b; }, + mod: function (a, b) { return a % b; }, + mul: function (a, b) { return a * b; }, + + // bitwise binary operators + and: function (a, b) { return a & b; }, + or: function (a, b) { return a | b; }, + xor: function (a, b) { return a ^ b; }, + lshift: function (a, b) { return a << b; }, + rshift: function (a, b) { return a >> b; }, + zrshift: function (a, b) { return a >>> b; }, + + // near-worthless built-in comparators + eq: function (a, b) { return a == b; }, + ne: function (a, b) { return a != b; }, + gt: function (a, b) { return a > b; }, + ge: function (a, b) { return a >= b; }, + lt: function (a, b) { return a < b; }, + le: function (a, b) { return a <= b; }, + + // compare comparators + ceq: function (a, b) { return MochiKit.Base.compare(a, b) === 0; }, + cne: function (a, b) { return MochiKit.Base.compare(a, b) !== 0; }, + cgt: function (a, b) { return MochiKit.Base.compare(a, b) == 1; }, + cge: function (a, b) { return MochiKit.Base.compare(a, b) != -1; }, + clt: function (a, b) { return MochiKit.Base.compare(a, b) == -1; }, + cle: function (a, b) { return MochiKit.Base.compare(a, b) != 1; }, + + // binary logical operators + logand: function (a, b) { return a && b; }, + logor: function (a, b) { return a || b; }, + contains: function (a, b) { return b in a; } + }, + + forwardCall: function (func) { + return function () { + return this[func].apply(this, arguments); + }; + }, + + itemgetter: function (func) { + return function (arg) { + return arg[func]; + }; + }, + + typeMatcher: function (/* typ */) { + var types = {}; + for (var i = 0; i < arguments.length; i++) { + var typ = arguments[i]; + types[typ] = typ; + } + return function () { + for (var i = 0; i < arguments.length; i++) { + if (!(typeof(arguments[i]) in types)) { + return false; + } + } + return true; + }; + }, + + isNull: function (/* ... */) { + for (var i = 0; i < arguments.length; i++) { + if (arguments[i] !== null) { + return false; + } + } + return true; + }, + + isUndefinedOrNull: function (/* ... */) { + for (var i = 0; i < arguments.length; i++) { + var o = arguments[i]; + if (!(typeof(o) == 'undefined' || o === null)) { + return false; + } + } + return true; + }, + + isEmpty: function (obj) { + return !MochiKit.Base.isNotEmpty.apply(this, arguments); + }, + + isNotEmpty: function (obj) { + for (var i = 0; i < arguments.length; i++) { + var o = arguments[i]; + if (!(o && o.length)) { + return false; + } + } + return true; + }, + + isArrayLike: function () { + for (var i = 0; i < arguments.length; i++) { + var o = arguments[i]; + var typ = typeof(o); + if ( + (typ != 'object' && !(typ == 'function' && typeof(o.item) == 'function')) || + o === null || + typeof(o.length) != 'number' + ) { + return false; + } + } + return true; + }, + + isDateLike: function () { + for (var i = 0; i < arguments.length; i++) { + var o = arguments[i]; + if (typeof(o) != "object" || o === null + || typeof(o.getTime) != 'function') { + return false; + } + } + return true; + }, + + + xmap: function (fn/*, obj... */) { + if (fn === null) { + return MochiKit.Base.extend(null, arguments, 1); + } + var rval = []; + for (var i = 1; i < arguments.length; i++) { + rval.push(fn(arguments[i])); + } + return rval; + }, + + map: function (fn, lst/*, lst... */) { + var m = MochiKit.Base; + var itr = MochiKit.Iter; + var isArrayLike = m.isArrayLike; + if (arguments.length <= 2) { + // allow an iterable to be passed + if (!isArrayLike(lst)) { + if (itr) { + // fast path for map(null, iterable) + lst = itr.list(lst); + if (fn === null) { + return lst; + } + } else { + throw new TypeError("Argument not an array-like and MochiKit.Iter not present"); + } + } + // fast path for map(null, lst) + if (fn === null) { + return m.extend(null, lst); + } + // disabled fast path for map(fn, lst) + /* + if (false && typeof(Array.prototype.map) == 'function') { + // Mozilla fast-path + return Array.prototype.map.call(lst, fn); + } + */ + var rval = []; + for (var i = 0; i < lst.length; i++) { + rval.push(fn(lst[i])); + } + return rval; + } else { + // default for map(null, ...) is zip(...) + if (fn === null) { + fn = Array; + } + var length = null; + for (i = 1; i < arguments.length; i++) { + // allow iterables to be passed + if (!isArrayLike(arguments[i])) { + if (itr) { + return itr.list(itr.imap.apply(null, arguments)); + } else { + throw new TypeError("Argument not an array-like and MochiKit.Iter not present"); + } + } + // find the minimum length + var l = arguments[i].length; + if (length === null || length > l) { + length = l; + } + } + rval = []; + for (i = 0; i < length; i++) { + var args = []; + for (var j = 1; j < arguments.length; j++) { + args.push(arguments[j][i]); + } + rval.push(fn.apply(this, args)); + } + return rval; + } + }, + + xfilter: function (fn/*, obj... */) { + var rval = []; + if (fn === null) { + fn = MochiKit.Base.operator.truth; + } + for (var i = 1; i < arguments.length; i++) { + var o = arguments[i]; + if (fn(o)) { + rval.push(o); + } + } + return rval; + }, + + filter: function (fn, lst, self) { + var rval = []; + // allow an iterable to be passed + var m = MochiKit.Base; + if (!m.isArrayLike(lst)) { + if (MochiKit.Iter) { + lst = MochiKit.Iter.list(lst); + } else { + throw new TypeError("Argument not an array-like and MochiKit.Iter not present"); + } + } + if (fn === null) { + fn = m.operator.truth; + } + if (typeof(Array.prototype.filter) == 'function') { + // Mozilla fast-path + return Array.prototype.filter.call(lst, fn, self); + } else if (typeof(self) == 'undefined' || self === null) { + for (var i = 0; i < lst.length; i++) { + var o = lst[i]; + if (fn(o)) { + rval.push(o); + } + } + } else { + for (i = 0; i < lst.length; i++) { + o = lst[i]; + if (fn.call(self, o)) { + rval.push(o); + } + } + } + return rval; + }, + + + _wrapDumbFunction: function (func) { + return function () { + // fast path! + switch (arguments.length) { + case 0: return func(); + case 1: return func(arguments[0]); + case 2: return func(arguments[0], arguments[1]); + case 3: return func(arguments[0], arguments[1], arguments[2]); + } + var args = []; + for (var i = 0; i < arguments.length; i++) { + args.push("arguments[" + i + "]"); + } + return eval("(func(" + args.join(",") + "))"); + }; + }, + + method: function (self, func) { + var m = MochiKit.Base; + return m.bind.apply(this, m.extend([func, self], arguments, 2)); + }, + + bind: function (func, self/* args... */) { + if (typeof(func) == "string") { + func = self[func]; + } + var im_func = func.im_func; + var im_preargs = func.im_preargs; + var im_self = func.im_self; + var m = MochiKit.Base; + if (typeof(func) == "function" && typeof(func.apply) == "undefined") { + // this is for cases where JavaScript sucks ass and gives you a + // really dumb built-in function like alert() that doesn't have + // an apply + func = m._wrapDumbFunction(func); + } + if (typeof(im_func) != 'function') { + im_func = func; + } + if (typeof(self) != 'undefined') { + im_self = self; + } + if (typeof(im_preargs) == 'undefined') { + im_preargs = []; + } else { + im_preargs = im_preargs.slice(); + } + m.extend(im_preargs, arguments, 2); + var newfunc = function () { + var args = arguments; + var me = arguments.callee; + if (me.im_preargs.length > 0) { + args = m.concat(me.im_preargs, args); + } + var self = me.im_self; + if (!self) { + self = this; + } + return me.im_func.apply(self, args); + }; + newfunc.im_self = im_self; + newfunc.im_func = im_func; + newfunc.im_preargs = im_preargs; + return newfunc; + }, + + bindMethods: function (self) { + var bind = MochiKit.Base.bind; + for (var k in self) { + var func = self[k]; + if (typeof(func) == 'function') { + self[k] = bind(func, self); + } + } + }, + + registerComparator: function (name, check, comparator, /* optional */ override) { + MochiKit.Base.comparatorRegistry.register(name, check, comparator, override); + }, + + _primitives: {'boolean': true, 'string': true, 'number': true}, + + compare: function (a, b) { + if (a == b) { + return 0; + } + var aIsNull = (typeof(a) == 'undefined' || a === null); + var bIsNull = (typeof(b) == 'undefined' || b === null); + if (aIsNull && bIsNull) { + return 0; + } else if (aIsNull) { + return -1; + } else if (bIsNull) { + return 1; + } + var m = MochiKit.Base; + // bool, number, string have meaningful comparisons + var prim = m._primitives; + if (!(typeof(a) in prim && typeof(b) in prim)) { + try { + return m.comparatorRegistry.match(a, b); + } catch (e) { + if (e != m.NotFound) { + throw e; + } + } + } + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } + // These types can't be compared + var repr = m.repr; + throw new TypeError(repr(a) + " and " + repr(b) + " can not be compared"); + }, + + compareDateLike: function (a, b) { + return MochiKit.Base.compare(a.getTime(), b.getTime()); + }, + + compareArrayLike: function (a, b) { + var compare = MochiKit.Base.compare; + var count = a.length; + var rval = 0; + if (count > b.length) { + rval = 1; + count = b.length; + } else if (count < b.length) { + rval = -1; + } + for (var i = 0; i < count; i++) { + var cmp = compare(a[i], b[i]); + if (cmp) { + return cmp; + } + } + return rval; + }, + + registerRepr: function (name, check, wrap, /* optional */override) { + MochiKit.Base.reprRegistry.register(name, check, wrap, override); + }, + + repr: function (o) { + if (typeof(o) == "undefined") { + return "undefined"; + } else if (o === null) { + return "null"; + } + try { + if (typeof(o.__repr__) == 'function') { + return o.__repr__(); + } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) { + return o.repr(); + } + return MochiKit.Base.reprRegistry.match(o); + } catch (e) { + if (typeof(o.NAME) == 'string' && ( + o.toString == Function.prototype.toString || + o.toString == Object.prototype.toString + )) { + return o.NAME; + } + } + try { + var ostring = (o + ""); + } catch (e) { + return "[" + typeof(o) + "]"; + } + if (typeof(o) == "function") { + o = ostring.replace(/^\s+/, ""); + var idx = o.indexOf("{"); + if (idx != -1) { + o = o.substr(0, idx) + "{...}"; + } + } + return ostring; + }, + + reprArrayLike: function (o) { + var m = MochiKit.Base; + return "[" + m.map(m.repr, o).join(", ") + "]"; + }, + + reprString: function (o) { + return ('"' + o.replace(/(["\\])/g, '\\$1') + '"' + ).replace(/[\f]/g, "\\f" + ).replace(/[\b]/g, "\\b" + ).replace(/[\n]/g, "\\n" + ).replace(/[\t]/g, "\\t" + ).replace(/[\r]/g, "\\r"); + }, + + reprNumber: function (o) { + return o + ""; + }, + + registerJSON: function (name, check, wrap, /* optional */override) { + MochiKit.Base.jsonRegistry.register(name, check, wrap, override); + }, + + + evalJSON: function () { + return eval("(" + arguments[0] + ")"); + }, + + serializeJSON: function (o) { + var objtype = typeof(o); + if (objtype == "undefined") { + return "undefined"; + } else if (objtype == "number" || objtype == "boolean") { + return o + ""; + } else if (o === null) { + return "null"; + } + var m = MochiKit.Base; + var reprString = m.reprString; + if (objtype == "string") { + return reprString(o); + } + // recurse + var me = arguments.callee; + // short-circuit for objects that support "json" serialization + // if they return "self" then just pass-through... + var newObj; + if (typeof(o.__json__) == "function") { + newObj = o.__json__(); + if (o !== newObj) { + return me(newObj); + } + } + if (typeof(o.json) == "function") { + newObj = o.json(); + if (o !== newObj) { + return me(newObj); + } + } + // array + if (objtype != "function" && typeof(o.length) == "number") { + var res = []; + for (var i = 0; i < o.length; i++) { + var val = me(o[i]); + if (typeof(val) != "string") { + val = "undefined"; + } + res.push(val); + } + return "[" + res.join(", ") + "]"; + } + // look in the registry + try { + newObj = m.jsonRegistry.match(o); + return me(newObj); + } catch (e) { + if (e != m.NotFound) { + // something really bad happened + throw e; + } + } + // it's a function with no adapter, bad + if (objtype == "function") { + return null; + } + // generic object code path + res = []; + for (var k in o) { + var useKey; + if (typeof(k) == "number") { + useKey = '"' + k + '"'; + } else if (typeof(k) == "string") { + useKey = reprString(k); + } else { + // skip non-string or number keys + continue; + } + val = me(o[k]); + if (typeof(val) != "string") { + // skip non-serializable values + continue; + } + res.push(useKey + ":" + val); + } + return "{" + res.join(", ") + "}"; + }, + + + objEqual: function (a, b) { + return (MochiKit.Base.compare(a, b) === 0); + }, + + arrayEqual: function (self, arr) { + if (self.length != arr.length) { + return false; + } + return (MochiKit.Base.compare(self, arr) === 0); + }, + + concat: function (/* lst... */) { + var rval = []; + var extend = MochiKit.Base.extend; + for (var i = 0; i < arguments.length; i++) { + extend(rval, arguments[i]); + } + return rval; + }, + + keyComparator: function (key/* ... */) { + // fast-path for single key comparisons + var m = MochiKit.Base; + var compare = m.compare; + if (arguments.length == 1) { + return function (a, b) { + return compare(a[key], b[key]); + }; + } + var compareKeys = m.extend(null, arguments); + return function (a, b) { + var rval = 0; + // keep comparing until something is inequal or we run out of + // keys to compare + for (var i = 0; (rval === 0) && (i < compareKeys.length); i++) { + var key = compareKeys[i]; + rval = compare(a[key], b[key]); + } + return rval; + }; + }, + + reverseKeyComparator: function (key) { + var comparator = MochiKit.Base.keyComparator.apply(this, arguments); + return function (a, b) { + return comparator(b, a); + }; + }, + + partial: function (func) { + var m = MochiKit.Base; + return m.bind.apply(this, m.extend([func, undefined], arguments, 1)); + }, + + listMinMax: function (which, lst) { + if (lst.length === 0) { + return null; + } + var cur = lst[0]; + var compare = MochiKit.Base.compare; + for (var i = 1; i < lst.length; i++) { + var o = lst[i]; + if (compare(o, cur) == which) { + cur = o; + } + } + return cur; + }, + + objMax: function (/* obj... */) { + return MochiKit.Base.listMinMax(1, arguments); + }, + + objMin: function (/* obj... */) { + return MochiKit.Base.listMinMax(-1, arguments); + }, + + findIdentical: function (lst, value, start/* = 0 */, /* optional */end) { + if (typeof(end) == "undefined" || end === null) { + end = lst.length; + } + for (var i = (start || 0); i < end; i++) { + if (lst[i] === value) { + return i; + } + } + return -1; + }, + + findValue: function (lst, value, start/* = 0 */, /* optional */end) { + if (typeof(end) == "undefined" || end === null) { + end = lst.length; + } + var cmp = MochiKit.Base.compare; + for (var i = (start || 0); i < end; i++) { + if (cmp(lst[i], value) === 0) { + return i; + } + } + return -1; + }, + + nodeWalk: function (node, visitor) { + var nodes = [node]; + var extend = MochiKit.Base.extend; + while (nodes.length) { + var res = visitor(nodes.shift()); + if (res) { + extend(nodes, res); + } + } + }, + + + nameFunctions: function (namespace) { + var base = namespace.NAME; + if (typeof(base) == 'undefined') { + base = ''; + } else { + base = base + '.'; + } + for (var name in namespace) { + var o = namespace[name]; + if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') { + try { + o.NAME = base + name; + } catch (e) { + // pass + } + } + } + }, + + + queryString: function (names, values) { + // check to see if names is a string or a DOM element, and if + // MochiKit.DOM is available. If so, drop it like it's a form + // Ugliest conditional in MochiKit? Probably! + if (typeof(MochiKit.DOM) != "undefined" && arguments.length == 1 + && (typeof(names) == "string" || ( + typeof(names.nodeType) != "undefined" && names.nodeType > 0 + )) + ) { + var kv = MochiKit.DOM.formContents(names); + names = kv[0]; + values = kv[1]; + } else if (arguments.length == 1) { + var o = names; + names = []; + values = []; + for (var k in o) { + var v = o[k]; + if (typeof(v) != "function") { + names.push(k); + values.push(v); + } + } + } + var rval = []; + var len = Math.min(names.length, values.length); + var urlEncode = MochiKit.Base.urlEncode; + for (var i = 0; i < len; i++) { + v = values[i]; + if (typeof(v) != 'undefined' && v !== null) { + rval.push(urlEncode(names[i]) + "=" + urlEncode(v)); + } + } + return rval.join("&"); + }, + + + parseQueryString: function (encodedString, useArrays) { + var pairs = encodedString.replace(/\+/g, "%20").split("&"); + var o = {}; + var decode; + if (typeof(decodeURIComponent) != "undefined") { + decode = decodeURIComponent; + } else { + decode = unescape; + } + if (useArrays) { + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i].split("="); + var name = decode(pair[0]); + var arr = o[name]; + if (!(arr instanceof Array)) { + arr = []; + o[name] = arr; + } + arr.push(decode(pair[1])); + } + } else { + for (i = 0; i < pairs.length; i++) { + pair = pairs[i].split("="); + o[decode(pair[0])] = decode(pair[1]); + } + } + return o; + } +}); + +MochiKit.Base.AdapterRegistry = function () { + this.pairs = []; +}; + +MochiKit.Base.AdapterRegistry.prototype = { + register: function (name, check, wrap, /* optional */ override) { + if (override) { + this.pairs.unshift([name, check, wrap]); + } else { + this.pairs.push([name, check, wrap]); + } + }, + + match: function (/* ... */) { + for (var i = 0; i < this.pairs.length; i++) { + var pair = this.pairs[i]; + if (pair[1].apply(this, arguments)) { + return pair[2].apply(this, arguments); + } + } + throw MochiKit.Base.NotFound; + }, + + unregister: function (name) { + for (var i = 0; i < this.pairs.length; i++) { + var pair = this.pairs[i]; + if (pair[0] == name) { + this.pairs.splice(i, 1); + return true; + } + } + return false; + } +}; + + +MochiKit.Base.EXPORT = [ + "counter", + "clone", + "extend", + "update", + "updatetree", + "setdefault", + "keys", + "items", + "NamedError", + "operator", + "forwardCall", + "itemgetter", + "typeMatcher", + "isCallable", + "isUndefined", + "isUndefinedOrNull", + "isNull", + "isEmpty", + "isNotEmpty", + "isArrayLike", + "isDateLike", + "xmap", + "map", + "xfilter", + "filter", + "bind", + "bindMethods", + "NotFound", + "AdapterRegistry", + "registerComparator", + "compare", + "registerRepr", + "repr", + "objEqual", + "arrayEqual", + "concat", + "keyComparator", + "reverseKeyComparator", + "partial", + "merge", + "listMinMax", + "listMax", + "listMin", + "objMax", + "objMin", + "nodeWalk", + "zip", + "urlEncode", + "queryString", + "serializeJSON", + "registerJSON", + "evalJSON", + "parseQueryString", + "findValue", + "findIdentical", + "flattenArguments", + "method" +]; + +MochiKit.Base.EXPORT_OK = [ + "nameFunctions", + "comparatorRegistry", + "reprRegistry", + "jsonRegistry", + "compareDateLike", + "compareArrayLike", + "reprArrayLike", + "reprString", + "reprNumber" +]; + +MochiKit.Base._exportSymbols = function (globals, module) { + if (typeof(MochiKit.__export__) == "undefined") { + MochiKit.__export__ = (MochiKit.__compat__ || + (typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined') + ); + } + if (!MochiKit.__export__) { + return; + } + var all = module.EXPORT_TAGS[":all"]; + for (var i = 0; i < all.length; i++) { + globals[all[i]] = module[all[i]]; + } +}; + +MochiKit.Base.__new__ = function () { + // A singleton raised when no suitable adapter is found + var m = this; + + // Backwards compat + m.forward = m.forwardCall; + m.find = m.findValue; + + if (typeof(encodeURIComponent) != "undefined") { + m.urlEncode = function (unencoded) { + return encodeURIComponent(unencoded).replace(/\'/g, '%27'); + }; + } else { + m.urlEncode = function (unencoded) { + return escape(unencoded + ).replace(/\+/g, '%2B' + ).replace(/\"/g,'%22' + ).rval.replace(/\'/g, '%27'); + }; + } + + m.NamedError = function (name) { + this.message = name; + this.name = name; + }; + m.NamedError.prototype = new Error(); + m.update(m.NamedError.prototype, { + repr: function () { + if (this.message && this.message != this.name) { + return this.name + "(" + m.repr(this.message) + ")"; + } else { + return this.name + "()"; + } + }, + toString: m.forwardCall("repr") + }); + + m.NotFound = new m.NamedError("MochiKit.Base.NotFound"); + + + m.listMax = m.partial(m.listMinMax, 1); + m.listMin = m.partial(m.listMinMax, -1); + + m.isCallable = m.typeMatcher('function'); + m.isUndefined = m.typeMatcher('undefined'); + + m.merge = m.partial(m.update, null); + m.zip = m.partial(m.map, null); + + m.comparatorRegistry = new m.AdapterRegistry(); + m.registerComparator("dateLike", m.isDateLike, m.compareDateLike); + m.registerComparator("arrayLike", m.isArrayLike, m.compareArrayLike); + + m.reprRegistry = new m.AdapterRegistry(); + m.registerRepr("arrayLike", m.isArrayLike, m.reprArrayLike); + m.registerRepr("string", m.typeMatcher("string"), m.reprString); + m.registerRepr("numbers", m.typeMatcher("number", "boolean"), m.reprNumber); + + m.jsonRegistry = new m.AdapterRegistry(); + + var all = m.concat(m.EXPORT, m.EXPORT_OK); + m.EXPORT_TAGS = { + ":common": m.concat(m.EXPORT_OK), + ":all": all + }; + + m.nameFunctions(this); + +}; + +MochiKit.Base.__new__(); + +// +// XXX: Internet Explorer blows +// +if (!MochiKit.__compat__) { + compare = MochiKit.Base.compare; +} + +MochiKit.Base._exportSymbols(this, MochiKit.Base); diff --git a/webtools/new-graph/js/mochikit/Color.js b/webtools/new-graph/js/mochikit/Color.js new file mode 100644 index 00000000000..aedf2d88125 --- /dev/null +++ b/webtools/new-graph/js/mochikit/Color.js @@ -0,0 +1,825 @@ +/*** + +MochiKit.Color 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito and others. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.Color'); + dojo.require('MochiKit.Base'); +} + +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Base", []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.Color depends on MochiKit.Base"; +} + +if (typeof(MochiKit.Color) == "undefined") { + MochiKit.Color = {}; +} + +MochiKit.Color.NAME = "MochiKit.Color"; +MochiKit.Color.VERSION = "1.3.1"; + +MochiKit.Color.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; + +MochiKit.Color.toString = function () { + return this.__repr__(); +}; + + +MochiKit.Color.Color = function (red, green, blue, alpha) { + if (typeof(alpha) == 'undefined' || alpha === null) { + alpha = 1.0; + } + this.rgb = { + r: red, + g: green, + b: blue, + a: alpha + }; +}; + + +// Prototype methods +MochiKit.Color.Color.prototype = { + + __class__: MochiKit.Color.Color, + + colorWithAlpha: function (alpha) { + var rgb = this.rgb; + var m = MochiKit.Color; + return m.Color.fromRGB(rgb.r, rgb.g, rgb.b, alpha); + }, + + colorWithHue: function (hue) { + // get an HSL model, and set the new hue... + var hsl = this.asHSL(); + hsl.h = hue; + var m = MochiKit.Color; + // convert back to RGB... + return m.Color.fromHSL(hsl); + }, + + colorWithSaturation: function (saturation) { + // get an HSL model, and set the new hue... + var hsl = this.asHSL(); + hsl.s = saturation; + var m = MochiKit.Color; + // convert back to RGB... + return m.Color.fromHSL(hsl); + }, + + colorWithLightness: function (lightness) { + // get an HSL model, and set the new hue... + var hsl = this.asHSL(); + hsl.l = lightness; + var m = MochiKit.Color; + // convert back to RGB... + return m.Color.fromHSL(hsl); + }, + + darkerColorWithLevel: function (level) { + var hsl = this.asHSL(); + hsl.l = Math.max(hsl.l - level, 0); + var m = MochiKit.Color; + return m.Color.fromHSL(hsl); + }, + + lighterColorWithLevel: function (level) { + var hsl = this.asHSL(); + hsl.l = Math.min(hsl.l + level, 1); + var m = MochiKit.Color; + return m.Color.fromHSL(hsl); + }, + + blendedColor: function (other, /* optional */ fraction) { + if (typeof(fraction) == 'undefined' || fraction === null) { + fraction = 0.5; + } + var sf = 1.0 - fraction; + var s = this.rgb; + var d = other.rgb; + var df = fraction; + return MochiKit.Color.Color.fromRGB( + (s.r * sf) + (d.r * df), + (s.g * sf) + (d.g * df), + (s.b * sf) + (d.b * df), + (s.a * sf) + (d.a * df) + ); + }, + + compareRGB: function (other) { + var a = this.asRGB(); + var b = other.asRGB(); + return MochiKit.Base.compare( + [a.r, a.g, a.b, a.a], + [b.r, b.g, b.b, b.a] + ); + }, + + isLight: function () { + return this.asHSL().b > 0.5; + }, + + isDark: function () { + return (!this.isLight()); + }, + + toHSLString: function () { + var c = this.asHSL(); + var ccc = MochiKit.Color.clampColorComponent; + var rval = this._hslString; + if (!rval) { + var mid = ( + ccc(c.h, 360).toFixed(0) + + "," + ccc(c.s, 100).toPrecision(4) + "%" + + "," + ccc(c.l, 100).toPrecision(4) + "%" + ); + var a = c.a; + if (a >= 1) { + a = 1; + rval = "hsl(" + mid + ")"; + } else { + if (a <= 0) { + a = 0; + } + rval = "hsla(" + mid + "," + a + ")"; + } + this._hslString = rval; + } + return rval; + }, + + toRGBString: function () { + var c = this.rgb; + var ccc = MochiKit.Color.clampColorComponent; + var rval = this._rgbString; + if (!rval) { + var mid = ( + ccc(c.r, 255).toFixed(0) + + "," + ccc(c.g, 255).toFixed(0) + + "," + ccc(c.b, 255).toFixed(0) + ); + if (c.a != 1) { + rval = "rgba(" + mid + "," + c.a + ")"; + } else { + rval = "rgb(" + mid + ")"; + } + this._rgbString = rval; + } + return rval; + }, + + asRGB: function () { + return MochiKit.Base.clone(this.rgb); + }, + + toHexString: function () { + var m = MochiKit.Color; + var c = this.rgb; + var ccc = MochiKit.Color.clampColorComponent; + var rval = this._hexString; + if (!rval) { + rval = ("#" + + m.toColorPart(ccc(c.r, 255)) + + m.toColorPart(ccc(c.g, 255)) + + m.toColorPart(ccc(c.b, 255)) + ); + this._hexString = rval; + } + return rval; + }, + + asHSV: function () { + var hsv = this.hsv; + var c = this.rgb; + if (typeof(hsv) == 'undefined' || hsv === null) { + hsv = MochiKit.Color.rgbToHSV(this.rgb); + this.hsv = hsv; + } + return MochiKit.Base.clone(hsv); + }, + + asHSL: function () { + var hsl = this.hsl; + var c = this.rgb; + if (typeof(hsl) == 'undefined' || hsl === null) { + hsl = MochiKit.Color.rgbToHSL(this.rgb); + this.hsl = hsl; + } + return MochiKit.Base.clone(hsl); + }, + + toString: function () { + return this.toRGBString(); + }, + + repr: function () { + var c = this.rgb; + var col = [c.r, c.g, c.b, c.a]; + return this.__class__.NAME + "(" + col.join(", ") + ")"; + } + +}; + +// Constructor methods +MochiKit.Base.update(MochiKit.Color.Color, { + fromRGB: function (red, green, blue, alpha) { + // designated initializer + var Color = MochiKit.Color.Color; + if (arguments.length == 1) { + var rgb = red; + red = rgb.r; + green = rgb.g; + blue = rgb.b; + if (typeof(rgb.a) == 'undefined') { + alpha = undefined; + } else { + alpha = rgb.a; + } + } + return new Color(red, green, blue, alpha); + }, + + fromHSL: function (hue, saturation, lightness, alpha) { + var m = MochiKit.Color; + return m.Color.fromRGB(m.hslToRGB.apply(m, arguments)); + }, + + fromHSV: function (hue, saturation, value, alpha) { + var m = MochiKit.Color; + return m.Color.fromRGB(m.hsvToRGB.apply(m, arguments)); + }, + + fromName: function (name) { + var Color = MochiKit.Color.Color; + // Opera 9 seems to "quote" named colors(?!) + if (name.charAt(0) == '"') { + name = name.substr(1, name.length - 2); + } + var htmlColor = Color._namedColors[name.toLowerCase()]; + if (typeof(htmlColor) == 'string') { + return Color.fromHexString(htmlColor); + } else if (name == "transparent") { + return Color.transparentColor(); + } + return null; + }, + + fromString: function (colorString) { + var self = MochiKit.Color.Color; + var three = colorString.substr(0, 3); + if (three == "rgb") { + return self.fromRGBString(colorString); + } else if (three == "hsl") { + return self.fromHSLString(colorString); + } else if (colorString.charAt(0) == "#") { + return self.fromHexString(colorString); + } + return self.fromName(colorString); + }, + + + fromHexString: function (hexCode) { + if (hexCode.charAt(0) == '#') { + hexCode = hexCode.substring(1); + } + var components = []; + var i, hex; + if (hexCode.length == 3) { + for (i = 0; i < 3; i++) { + hex = hexCode.substr(i, 1); + components.push(parseInt(hex + hex, 16) / 255.0); + } + } else { + for (i = 0; i < 6; i += 2) { + hex = hexCode.substr(i, 2); + components.push(parseInt(hex, 16) / 255.0); + } + } + var Color = MochiKit.Color.Color; + return Color.fromRGB.apply(Color, components); + }, + + + _fromColorString: function (pre, method, scales, colorCode) { + // parses either HSL or RGB + if (colorCode.indexOf(pre) === 0) { + colorCode = colorCode.substring(colorCode.indexOf("(", 3) + 1, colorCode.length - 1); + } + var colorChunks = colorCode.split(/\s*,\s*/); + var colorFloats = []; + for (var i = 0; i < colorChunks.length; i++) { + var c = colorChunks[i]; + var val; + var three = c.substring(c.length - 3); + if (c.charAt(c.length - 1) == '%') { + val = 0.01 * parseFloat(c.substring(0, c.length - 1)); + } else if (three == "deg") { + val = parseFloat(c) / 360.0; + } else if (three == "rad") { + val = parseFloat(c) / (Math.PI * 2); + } else { + val = scales[i] * parseFloat(c); + } + colorFloats.push(val); + } + return this[method].apply(this, colorFloats); + }, + + fromComputedStyle: function (elem, style, mozillaEquivalentCSS) { + var d = MochiKit.DOM; + var cls = MochiKit.Color.Color; + for (elem = d.getElement(elem); elem; elem = elem.parentNode) { + var actualColor = d.computedStyle.apply(d, arguments); + if (!actualColor) { + continue; + } + var color = cls.fromString(actualColor); + if (!color) { + break; + } + if (color.asRGB().a > 0) { + return color; + } + } + return null; + }, + + fromBackground: function (elem) { + var cls = MochiKit.Color.Color; + return cls.fromComputedStyle( + elem, "backgroundColor", "background-color") || cls.whiteColor(); + }, + + fromText: function (elem) { + var cls = MochiKit.Color.Color; + return cls.fromComputedStyle( + elem, "color", "color") || cls.blackColor(); + }, + + namedColors: function () { + return MochiKit.Base.clone(MochiKit.Color.Color._namedColors); + } +}); + +// Module level functions +MochiKit.Base.update(MochiKit.Color, { + clampColorComponent: function (v, scale) { + v *= scale; + if (v < 0) { + return 0; + } else if (v > scale) { + return scale; + } else { + return v; + } + }, + + _hslValue: function (n1, n2, hue) { + if (hue > 6.0) { + hue -= 6.0; + } else if (hue < 0.0) { + hue += 6.0; + } + var val; + if (hue < 1.0) { + val = n1 + (n2 - n1) * hue; + } else if (hue < 3.0) { + val = n2; + } else if (hue < 4.0) { + val = n1 + (n2 - n1) * (4.0 - hue); + } else { + val = n1; + } + return val; + }, + + hsvToRGB: function (hue, saturation, value, alpha) { + if (arguments.length == 1) { + var hsv = hue; + hue = hsv.h; + saturation = hsv.s; + value = hsv.v; + alpha = hsv.a; + } + var red; + var green; + var blue; + if (saturation === 0) { + red = 0; + green = 0; + blue = 0; + } else { + var i = Math.floor(hue * 6); + var f = (hue * 6) - i; + var p = value * (1 - saturation); + var q = value * (1 - (saturation * f)); + var t = value * (1 - (saturation * (1 - f))); + switch (i) { + case 1: red = q; green = value; blue = p; break; + case 2: red = p; green = value; blue = t; break; + case 3: red = p; green = q; blue = value; break; + case 4: red = t; green = p; blue = value; break; + case 5: red = value; green = p; blue = q; break; + case 6: // fall through + case 0: red = value; green = t; blue = p; break; + } + } + return { + r: red, + g: green, + b: blue, + a: alpha + }; + }, + + hslToRGB: function (hue, saturation, lightness, alpha) { + if (arguments.length == 1) { + var hsl = hue; + hue = hsl.h; + saturation = hsl.s; + lightness = hsl.l; + alpha = hsl.a; + } + var red; + var green; + var blue; + if (saturation === 0) { + red = lightness; + green = lightness; + blue = lightness; + } else { + var m2; + if (lightness <= 0.5) { + m2 = lightness * (1.0 + saturation); + } else { + m2 = lightness + saturation - (lightness * saturation); + } + var m1 = (2.0 * lightness) - m2; + var f = MochiKit.Color._hslValue; + var h6 = hue * 6.0; + red = f(m1, m2, h6 + 2); + green = f(m1, m2, h6); + blue = f(m1, m2, h6 - 2); + } + return { + r: red, + g: green, + b: blue, + a: alpha + }; + }, + + rgbToHSV: function (red, green, blue, alpha) { + if (arguments.length == 1) { + var rgb = red; + red = rgb.r; + green = rgb.g; + blue = rgb.b; + alpha = rgb.a; + } + var max = Math.max(Math.max(red, green), blue); + var min = Math.min(Math.min(red, green), blue); + var hue; + var saturation; + var value = max; + if (min == max) { + hue = 0; + saturation = 0; + } else { + var delta = (max - min); + saturation = delta / max; + + if (red == max) { + hue = (green - blue) / delta; + } else if (green == max) { + hue = 2 + ((blue - red) / delta); + } else { + hue = 4 + ((red - green) / delta); + } + hue /= 6; + if (hue < 0) { + hue += 1; + } + if (hue > 1) { + hue -= 1; + } + } + return { + h: hue, + s: saturation, + v: value, + a: alpha + }; + }, + + rgbToHSL: function (red, green, blue, alpha) { + if (arguments.length == 1) { + var rgb = red; + red = rgb.r; + green = rgb.g; + blue = rgb.b; + alpha = rgb.a; + } + var max = Math.max(red, Math.max(green, blue)); + var min = Math.min(red, Math.min(green, blue)); + var hue; + var saturation; + var lightness = (max + min) / 2.0; + var delta = max - min; + if (delta === 0) { + hue = 0; + saturation = 0; + } else { + if (lightness <= 0.5) { + saturation = delta / (max + min); + } else { + saturation = delta / (2 - max - min); + } + if (red == max) { + hue = (green - blue) / delta; + } else if (green == max) { + hue = 2 + ((blue - red) / delta); + } else { + hue = 4 + ((red - green) / delta); + } + hue /= 6; + if (hue < 0) { + hue += 1; + } + if (hue > 1) { + hue -= 1; + } + + } + return { + h: hue, + s: saturation, + l: lightness, + a: alpha + }; + }, + + toColorPart: function (num) { + num = Math.round(num); + var digits = num.toString(16); + if (num < 16) { + return '0' + digits; + } + return digits; + }, + + __new__: function () { + var m = MochiKit.Base; + this.Color.fromRGBString = m.bind( + this.Color._fromColorString, this.Color, "rgb", "fromRGB", + [1.0/255.0, 1.0/255.0, 1.0/255.0, 1] + ); + this.Color.fromHSLString = m.bind( + this.Color._fromColorString, this.Color, "hsl", "fromHSL", + [1.0/360.0, 0.01, 0.01, 1] + ); + + var third = 1.0 / 3.0; + var colors = { + // NSColor colors plus transparent + black: [0, 0, 0], + blue: [0, 0, 1], + brown: [0.6, 0.4, 0.2], + cyan: [0, 1, 1], + darkGray: [third, third, third], + gray: [0.5, 0.5, 0.5], + green: [0, 1, 0], + lightGray: [2 * third, 2 * third, 2 * third], + magenta: [1, 0, 1], + orange: [1, 0.5, 0], + purple: [0.5, 0, 0.5], + red: [1, 0, 0], + transparent: [0, 0, 0, 0], + white: [1, 1, 1], + yellow: [1, 1, 0] + }; + + var makeColor = function (name, r, g, b, a) { + var rval = this.fromRGB(r, g, b, a); + this[name] = function () { return rval; }; + return rval; + }; + + for (var k in colors) { + var name = k + "Color"; + var bindArgs = m.concat( + [makeColor, this.Color, name], + colors[k] + ); + this.Color[name] = m.bind.apply(null, bindArgs); + } + + var isColor = function () { + for (var i = 0; i < arguments.length; i++) { + if (!(arguments[i] instanceof Color)) { + return false; + } + } + return true; + }; + + var compareColor = function (a, b) { + return a.compareRGB(b); + }; + + m.nameFunctions(this); + + m.registerComparator(this.Color.NAME, isColor, compareColor); + + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": m.concat(this.EXPORT, this.EXPORT_OK) + }; + + } +}); + +MochiKit.Color.EXPORT = [ + "Color" +]; + +MochiKit.Color.EXPORT_OK = [ + "clampColorComponent", + "rgbToHSL", + "hslToRGB", + "rgbToHSV", + "hsvToRGB", + "toColorPart" +]; + +MochiKit.Color.__new__(); + +MochiKit.Base._exportSymbols(this, MochiKit.Color); + +// Full table of css3 X11 colors + +MochiKit.Color.Color._namedColors = { + aliceblue: "#f0f8ff", + antiquewhite: "#faebd7", + aqua: "#00ffff", + aquamarine: "#7fffd4", + azure: "#f0ffff", + beige: "#f5f5dc", + bisque: "#ffe4c4", + black: "#000000", + blanchedalmond: "#ffebcd", + blue: "#0000ff", + blueviolet: "#8a2be2", + brown: "#a52a2a", + burlywood: "#deb887", + cadetblue: "#5f9ea0", + chartreuse: "#7fff00", + chocolate: "#d2691e", + coral: "#ff7f50", + cornflowerblue: "#6495ed", + cornsilk: "#fff8dc", + crimson: "#dc143c", + cyan: "#00ffff", + darkblue: "#00008b", + darkcyan: "#008b8b", + darkgoldenrod: "#b8860b", + darkgray: "#a9a9a9", + darkgreen: "#006400", + darkgrey: "#a9a9a9", + darkkhaki: "#bdb76b", + darkmagenta: "#8b008b", + darkolivegreen: "#556b2f", + darkorange: "#ff8c00", + darkorchid: "#9932cc", + darkred: "#8b0000", + darksalmon: "#e9967a", + darkseagreen: "#8fbc8f", + darkslateblue: "#483d8b", + darkslategray: "#2f4f4f", + darkslategrey: "#2f4f4f", + darkturquoise: "#00ced1", + darkviolet: "#9400d3", + deeppink: "#ff1493", + deepskyblue: "#00bfff", + dimgray: "#696969", + dimgrey: "#696969", + dodgerblue: "#1e90ff", + firebrick: "#b22222", + floralwhite: "#fffaf0", + forestgreen: "#228b22", + fuchsia: "#ff00ff", + gainsboro: "#dcdcdc", + ghostwhite: "#f8f8ff", + gold: "#ffd700", + goldenrod: "#daa520", + gray: "#808080", + green: "#008000", + greenyellow: "#adff2f", + grey: "#808080", + honeydew: "#f0fff0", + hotpink: "#ff69b4", + indianred: "#cd5c5c", + indigo: "#4b0082", + ivory: "#fffff0", + khaki: "#f0e68c", + lavender: "#e6e6fa", + lavenderblush: "#fff0f5", + lawngreen: "#7cfc00", + lemonchiffon: "#fffacd", + lightblue: "#add8e6", + lightcoral: "#f08080", + lightcyan: "#e0ffff", + lightgoldenrodyellow: "#fafad2", + lightgray: "#d3d3d3", + lightgreen: "#90ee90", + lightgrey: "#d3d3d3", + lightpink: "#ffb6c1", + lightsalmon: "#ffa07a", + lightseagreen: "#20b2aa", + lightskyblue: "#87cefa", + lightslategray: "#778899", + lightslategrey: "#778899", + lightsteelblue: "#b0c4de", + lightyellow: "#ffffe0", + lime: "#00ff00", + limegreen: "#32cd32", + linen: "#faf0e6", + magenta: "#ff00ff", + maroon: "#800000", + mediumaquamarine: "#66cdaa", + mediumblue: "#0000cd", + mediumorchid: "#ba55d3", + mediumpurple: "#9370db", + mediumseagreen: "#3cb371", + mediumslateblue: "#7b68ee", + mediumspringgreen: "#00fa9a", + mediumturquoise: "#48d1cc", + mediumvioletred: "#c71585", + midnightblue: "#191970", + mintcream: "#f5fffa", + mistyrose: "#ffe4e1", + moccasin: "#ffe4b5", + navajowhite: "#ffdead", + navy: "#000080", + oldlace: "#fdf5e6", + olive: "#808000", + olivedrab: "#6b8e23", + orange: "#ffa500", + orangered: "#ff4500", + orchid: "#da70d6", + palegoldenrod: "#eee8aa", + palegreen: "#98fb98", + paleturquoise: "#afeeee", + palevioletred: "#db7093", + papayawhip: "#ffefd5", + peachpuff: "#ffdab9", + peru: "#cd853f", + pink: "#ffc0cb", + plum: "#dda0dd", + powderblue: "#b0e0e6", + purple: "#800080", + red: "#ff0000", + rosybrown: "#bc8f8f", + royalblue: "#4169e1", + saddlebrown: "#8b4513", + salmon: "#fa8072", + sandybrown: "#f4a460", + seagreen: "#2e8b57", + seashell: "#fff5ee", + sienna: "#a0522d", + silver: "#c0c0c0", + skyblue: "#87ceeb", + slateblue: "#6a5acd", + slategray: "#708090", + slategrey: "#708090", + snow: "#fffafa", + springgreen: "#00ff7f", + steelblue: "#4682b4", + tan: "#d2b48c", + teal: "#008080", + thistle: "#d8bfd8", + tomato: "#ff6347", + turquoise: "#40e0d0", + violet: "#ee82ee", + wheat: "#f5deb3", + white: "#ffffff", + whitesmoke: "#f5f5f5", + yellow: "#ffff00", + yellowgreen: "#9acd32" +}; diff --git a/webtools/new-graph/js/mochikit/DOM.js b/webtools/new-graph/js/mochikit/DOM.js new file mode 100644 index 00000000000..0449ccdc906 --- /dev/null +++ b/webtools/new-graph/js/mochikit/DOM.js @@ -0,0 +1,1106 @@ +/*** + +MochiKit.DOM 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide("MochiKit.DOM"); + dojo.require("MochiKit.Iter"); +} +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Iter", []); +} + +try { + if (typeof(MochiKit.Iter) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.DOM depends on MochiKit.Iter!"; +} + +if (typeof(MochiKit.DOM) == 'undefined') { + MochiKit.DOM = {}; +} + +MochiKit.DOM.NAME = "MochiKit.DOM"; +MochiKit.DOM.VERSION = "1.3.1"; +MochiKit.DOM.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; +MochiKit.DOM.toString = function () { + return this.__repr__(); +}; + +MochiKit.DOM.EXPORT = [ + "formContents", + "currentWindow", + "currentDocument", + "withWindow", + "withDocument", + "registerDOMConverter", + "coerceToDOM", + "createDOM", + "createDOMFunc", + "getNodeAttribute", + "setNodeAttribute", + "updateNodeAttributes", + "appendChildNodes", + "replaceChildNodes", + "removeElement", + "swapDOM", + "BUTTON", + "TT", + "PRE", + "H1", + "H2", + "H3", + "BR", + "CANVAS", + "HR", + "LABEL", + "TEXTAREA", + "FORM", + "STRONG", + "SELECT", + "OPTION", + "OPTGROUP", + "LEGEND", + "FIELDSET", + "P", + "UL", + "OL", + "LI", + "TD", + "TR", + "THEAD", + "TBODY", + "TFOOT", + "TABLE", + "TH", + "INPUT", + "SPAN", + "A", + "DIV", + "IMG", + "getElement", + "$", + "computedStyle", + "getElementsByTagAndClassName", + "addToCallStack", + "addLoadEvent", + "focusOnLoad", + "setElementClass", + "toggleElementClass", + "addElementClass", + "removeElementClass", + "swapElementClass", + "hasElementClass", + "escapeHTML", + "toHTML", + "emitHTML", + "setDisplayForElement", + "hideElement", + "showElement", + "scrapeText", + "elementDimensions", + "elementPosition", + "setElementDimensions", + "setElementPosition", + "getViewportDimensions", + "setOpacity" +]; + +MochiKit.DOM.EXPORT_OK = [ + "domConverters" +]; + +MochiKit.DOM.Dimensions = function (w, h) { + this.w = w; + this.h = h; +}; + +MochiKit.DOM.Dimensions.prototype.repr = function () { + var repr = MochiKit.Base.repr; + return "{w: " + repr(this.w) + ", h: " + repr(this.h) + "}"; +}; + +MochiKit.DOM.Coordinates = function (x, y) { + this.x = x; + this.y = y; +}; + +MochiKit.DOM.Coordinates.prototype.repr = function () { + var repr = MochiKit.Base.repr; + return "{x: " + repr(this.x) + ", y: " + repr(this.y) + "}"; +}; + +MochiKit.DOM.Coordinates.prototype.toString = function () { + return this.repr(); +}; + +MochiKit.Base.update(MochiKit.DOM, { + + setOpacity: function(elem, o) { + elem = MochiKit.DOM.getElement(elem); + MochiKit.DOM.updateNodeAttributes(elem, {'style': { + 'opacity': o, + '-moz-opacity': o, + '-khtml-opacity': o, + 'filter':' alpha(opacity=' + (o * 100) + ')' + }}); + }, + + getViewportDimensions: function() { + var d = new MochiKit.DOM.Dimensions(); + + var w = MochiKit.DOM._window; + var b = MochiKit.DOM._document.body; + + if (w.innerWidth) { + d.w = w.innerWidth; + d.h = w.innerHeight; + } else if (b.parentElement.clientWidth) { + d.w = b.parentElement.clientWidth; + d.h = b.parentElement.clientHeight; + } else if (b && b.clientWidth) { + d.w = b.clientWidth; + d.h = b.clientHeight; + } + return d; + }, + + elementDimensions: function (elem) { + var self = MochiKit.DOM; + if (typeof(elem.w) == 'number' || typeof(elem.h) == 'number') { + return new self.Dimensions(elem.w || 0, elem.h || 0); + } + elem = self.getElement(elem); + if (!elem) { + return undefined; + } + if (self.computedStyle(elem, 'display') != 'none') { + return new self.Dimensions(elem.offsetWidth || 0, + elem.offsetHeight || 0); + } + var s = elem.style; + var originalVisibility = s.visibility; + var originalPosition = s.position; + s.visibility = 'hidden'; + s.position = 'absolute'; + s.display = ''; + var originalWidth = elem.offsetWidth; + var originalHeight = elem.offsetHeight; + s.display = 'none'; + s.position = originalPosition; + s.visibility = originalVisibility; + return new self.Dimensions(originalWidth, originalHeight); + }, + + /* + + elementPosition is adapted from YAHOO.util.Dom.getXY, version 0.9.0. + Copyright: Copyright (c) 2006, Yahoo! Inc. All rights reserved. + License: BSD, http://developer.yahoo.net/yui/license.txt + + */ + elementPosition: function (elem, /* optional */relativeTo) { + var self = MochiKit.DOM; + elem = self.getElement(elem); + + if (!elem) { + return undefined; + } + + var c = new self.Coordinates(0, 0); + + if (elem.x && elem.y) { + /* it's just a MochiKit.DOM.Coordinates object */ + c.x += elem.x || 0; + c.y += elem.y || 0; + return c; + } else if (elem.parentNode === null || self.computedStyle(elem, 'display') == 'none') { + return undefined; + } + + var box = null; + var parent = null; + + var d = MochiKit.DOM._document; + var de = d.documentElement; + var b = d.body; + + if (elem.getBoundingClientRect) { // IE shortcut + + /* + + The IE shortcut is off by two: + http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp + + */ + box = elem.getBoundingClientRect(); + + c.x += box.left + + (de.scrollLeft || b.scrollLeft) - + (de.clientLeft || b.clientLeft); + + c.y += box.top + + (de.scrollTop || b.scrollTop) - + (de.clientTop || b.clientTop); + + } else if (d.getBoxObjectFor) { // Gecko shortcut + box = d.getBoxObjectFor(elem); + c.x += box.x; + c.y += box.y; + } else if (elem.offsetParent) { + c.x += elem.offsetLeft; + c.y += elem.offsetTop; + parent = elem.offsetParent; + + if (parent != elem) { + while (parent) { + c.x += parent.offsetLeft; + c.y += parent.offsetTop; + parent = parent.offsetParent; + } + } + + /* + + Opera < 9 and old Safari (absolute) incorrectly account for + body offsetTop and offsetLeft. + + */ + var ua = navigator.userAgent.toLowerCase(); + if ((typeof(opera) != "undefined" && + parseFloat(opera.version()) < 9) || + (ua.indexOf('safari') != -1 && + self.computedStyle(elem, 'position') == 'absolute')) { + + c.x -= b.offsetLeft; + c.y -= b.offsetTop; + + } + } + + if (typeof(relativeTo) != 'undefined') { + relativeTo = arguments.callee(relativeTo); + if (relativeTo) { + c.x -= (relativeTo.x || 0); + c.y -= (relativeTo.y || 0); + } + } + + if (elem.parentNode) { + parent = elem.parentNode; + } else { + parent = null; + } + + while (parent && parent.tagName != 'BODY' && + parent.tagName != 'HTML') { + c.x -= parent.scrollLeft; + c.y -= parent.scrollTop; + if (parent.parentNode) { + parent = parent.parentNode; + } else { + parent = null; + } + } + + return c; + }, + + setElementDimensions: function (elem, newSize/* optional */, units) { + elem = MochiKit.DOM.getElement(elem); + if (typeof(units) == 'undefined') { + units = 'px'; + } + MochiKit.DOM.updateNodeAttributes(elem, {'style': { + 'width': newSize.w + units, + 'height': newSize.h + units + }}); + }, + + setElementPosition: function (elem, newPos/* optional */, units) { + elem = MochiKit.DOM.getElement(elem); + if (typeof(units) == 'undefined') { + units = 'px'; + } + MochiKit.DOM.updateNodeAttributes(elem, {'style': { + 'left': newPos.x + units, + 'top': newPos.y + units + }}); + }, + + currentWindow: function () { + return MochiKit.DOM._window; + }, + + currentDocument: function () { + return MochiKit.DOM._document; + }, + + withWindow: function (win, func) { + var self = MochiKit.DOM; + var oldDoc = self._document; + var oldWin = self._win; + var rval; + try { + self._window = win; + self._document = win.document; + rval = func(); + } catch (e) { + self._window = oldWin; + self._document = oldDoc; + throw e; + } + self._window = oldWin; + self._document = oldDoc; + return rval; + }, + + formContents: function (elem/* = document */) { + var names = []; + var values = []; + var m = MochiKit.Base; + var self = MochiKit.DOM; + if (typeof(elem) == "undefined" || elem === null) { + elem = self._document; + } else { + elem = self.getElement(elem); + } + m.nodeWalk(elem, function (elem) { + var name = elem.name; + if (m.isNotEmpty(name)) { + var tagName = elem.nodeName; + if (tagName == "INPUT" + && (elem.type == "radio" || elem.type == "checkbox") + && !elem.checked + ) { + return null; + } + if (tagName == "SELECT") { + if (elem.selectedIndex >= 0) { + var opt = elem.options[elem.selectedIndex]; + names.push(name); + values.push((opt.value) ? opt.value : opt.text); + return null; + } + // no form elements? + names.push(name); + values.push(""); + return null; + } + if (tagName == "FORM" || tagName == "P" || tagName == "SPAN" + || tagName == "DIV" + ) { + return elem.childNodes; + } + names.push(name); + values.push(elem.value || ''); + return null; + } + return elem.childNodes; + }); + return [names, values]; + }, + + withDocument: function (doc, func) { + var self = MochiKit.DOM; + var oldDoc = self._document; + var rval; + try { + self._document = doc; + rval = func(); + } catch (e) { + self._document = oldDoc; + throw e; + } + self._document = oldDoc; + return rval; + }, + + registerDOMConverter: function (name, check, wrap, /* optional */override) { + MochiKit.DOM.domConverters.register(name, check, wrap, override); + }, + + coerceToDOM: function (node, ctx) { + var im = MochiKit.Iter; + var self = MochiKit.DOM; + var iter = im.iter; + var repeat = im.repeat; + var imap = im.imap; + var domConverters = self.domConverters; + var coerceToDOM = self.coerceToDOM; + var NotFound = MochiKit.Base.NotFound; + while (true) { + if (typeof(node) == 'undefined' || node === null) { + return null; + } + if (typeof(node.nodeType) != 'undefined' && node.nodeType > 0) { + return node; + } + if (typeof(node) == 'number' || typeof(node) == 'boolean') { + node = node.toString(); + // FALL THROUGH + } + if (typeof(node) == 'string') { + return self._document.createTextNode(node); + } + if (typeof(node.toDOM) == 'function') { + node = node.toDOM(ctx); + continue; + } + if (typeof(node) == 'function') { + node = node(ctx); + continue; + } + + // iterable + var iterNodes = null; + try { + iterNodes = iter(node); + } catch (e) { + // pass + } + if (iterNodes) { + return imap( + coerceToDOM, + iterNodes, + repeat(ctx) + ); + } + + // adapter + try { + node = domConverters.match(node, ctx); + continue; + } catch (e) { + if (e != NotFound) { + throw e; + } + } + + // fallback + return self._document.createTextNode(node.toString()); + } + // mozilla warnings aren't too bright + return undefined; + }, + + setNodeAttribute: function (node, attr, value) { + var o = {}; + o[attr] = value; + try { + return MochiKit.DOM.updateNodeAttributes(node, o); + } catch (e) { + // pass + } + return null; + }, + + getNodeAttribute: function (node, attr) { + var self = MochiKit.DOM; + var rename = self.attributeArray.renames[attr]; + node = self.getElement(node); + try { + if (rename) { + return node[rename]; + } + return node.getAttribute(attr); + } catch (e) { + // pass + } + return null; + }, + + updateNodeAttributes: function (node, attrs) { + var elem = node; + var self = MochiKit.DOM; + if (typeof(node) == 'string') { + elem = self.getElement(node); + } + if (attrs) { + var updatetree = MochiKit.Base.updatetree; + if (self.attributeArray.compliant) { + // not IE, good. + for (var k in attrs) { + var v = attrs[k]; + if (typeof(v) == 'object' && typeof(elem[k]) == 'object') { + updatetree(elem[k], v); + } else if (k.substring(0, 2) == "on") { + if (typeof(v) == "string") { + v = new Function(v); + } + elem[k] = v; + } else { + elem.setAttribute(k, v); + } + } + } else { + // IE is insane in the membrane + var renames = self.attributeArray.renames; + for (k in attrs) { + v = attrs[k]; + var renamed = renames[k]; + if (k == "style" && typeof(v) == "string") { + elem.style.cssText = v; + } else if (typeof(renamed) == "string") { + elem[renamed] = v; + } else if (typeof(elem[k]) == 'object' + && typeof(v) == 'object') { + updatetree(elem[k], v); + } else if (k.substring(0, 2) == "on") { + if (typeof(v) == "string") { + v = new Function(v); + } + elem[k] = v; + } else { + elem.setAttribute(k, v); + } + } + } + } + return elem; + }, + + appendChildNodes: function (node/*, nodes...*/) { + var elem = node; + var self = MochiKit.DOM; + if (typeof(node) == 'string') { + elem = self.getElement(node); + } + var nodeStack = [ + self.coerceToDOM( + MochiKit.Base.extend(null, arguments, 1), + elem + ) + ]; + var concat = MochiKit.Base.concat; + while (nodeStack.length) { + var n = nodeStack.shift(); + if (typeof(n) == 'undefined' || n === null) { + // pass + } else if (typeof(n.nodeType) == 'number') { + elem.appendChild(n); + } else { + nodeStack = concat(n, nodeStack); + } + } + return elem; + }, + + replaceChildNodes: function (node/*, nodes...*/) { + var elem = node; + var self = MochiKit.DOM; + if (typeof(node) == 'string') { + elem = self.getElement(node); + arguments[0] = elem; + } + var child; + while ((child = elem.firstChild)) { + elem.removeChild(child); + } + if (arguments.length < 2) { + return elem; + } else { + return self.appendChildNodes.apply(this, arguments); + } + }, + + createDOM: function (name, attrs/*, nodes... */) { + /* + + Create a DOM fragment in a really convenient manner, much like + Nevow's stan. + + */ + + var elem; + var self = MochiKit.DOM; + var m = MochiKit.Base; + if (typeof(attrs) == "string" || typeof(attrs) == "number") { + var args = m.extend([name, null], arguments, 1); + return arguments.callee.apply(this, args); + } + if (typeof(name) == 'string') { + // Internet Explorer is dumb + if (attrs && "name" in attrs && !self.attributeArray.compliant) { + // http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp + name = ('<' + name + ' name="' + self.escapeHTML(attrs.name) + + '">'); + } + elem = self._document.createElement(name); + } else { + elem = name; + } + if (attrs) { + self.updateNodeAttributes(elem, attrs); + } + if (arguments.length <= 2) { + return elem; + } else { + var args = m.extend([elem], arguments, 2); + return self.appendChildNodes.apply(this, args); + } + }, + + createDOMFunc: function (/* tag, attrs, *nodes */) { + var m = MochiKit.Base; + return m.partial.apply( + this, + m.extend([MochiKit.DOM.createDOM], arguments) + ); + }, + + swapDOM: function (dest, src) { + var self = MochiKit.DOM; + dest = self.getElement(dest); + var parent = dest.parentNode; + if (src) { + src = self.getElement(src); + parent.replaceChild(src, dest); + } else { + parent.removeChild(dest); + } + return src; + }, + + getElement: function (id) { + var self = MochiKit.DOM; + if (arguments.length == 1) { + return ((typeof(id) == "string") ? + self._document.getElementById(id) : id); + } else { + return MochiKit.Base.map(self.getElement, arguments); + } + }, + + computedStyle: function (htmlElement, cssProperty, mozillaEquivalentCSS) { + if (arguments.length == 2) { + mozillaEquivalentCSS = cssProperty; + } + var self = MochiKit.DOM; + var el = self.getElement(htmlElement); + var document = self._document; + if (!el || el == document) { + return undefined; + } + if (el.currentStyle) { + return el.currentStyle[cssProperty]; + } + if (typeof(document.defaultView) == 'undefined') { + return undefined; + } + if (document.defaultView === null) { + return undefined; + } + var style = document.defaultView.getComputedStyle(el, null); + if (typeof(style) == "undefined" || style === null) { + return undefined; + } + return style.getPropertyValue(mozillaEquivalentCSS); + }, + + getElementsByTagAndClassName: function (tagName, className, + /* optional */parent) { + var self = MochiKit.DOM; + if (typeof(tagName) == 'undefined' || tagName === null) { + tagName = '*'; + } + if (typeof(parent) == 'undefined' || parent === null) { + parent = self._document; + } + parent = self.getElement(parent); + var children = (parent.getElementsByTagName(tagName) + || self._document.all); + if (typeof(className) == 'undefined' || className === null) { + return MochiKit.Base.extend(null, children); + } + + var elements = []; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + var classNames = child.className.split(' '); + for (var j = 0; j < classNames.length; j++) { + if (classNames[j] == className) { + elements.push(child); + break; + } + } + } + + return elements; + }, + + _newCallStack: function (path, once) { + var rval = function () { + var callStack = arguments.callee.callStack; + for (var i = 0; i < callStack.length; i++) { + if (callStack[i].apply(this, arguments) === false) { + break; + } + } + if (once) { + try { + this[path] = null; + } catch (e) { + // pass + } + } + }; + rval.callStack = []; + return rval; + }, + + addToCallStack: function (target, path, func, once) { + var self = MochiKit.DOM; + var existing = target[path]; + var regfunc = existing; + if (!(typeof(existing) == 'function' + && typeof(existing.callStack) == "object" + && existing.callStack !== null)) { + regfunc = self._newCallStack(path, once); + if (typeof(existing) == 'function') { + regfunc.callStack.push(existing); + } + target[path] = regfunc; + } + regfunc.callStack.push(func); + }, + + addLoadEvent: function (func) { + var self = MochiKit.DOM; + self.addToCallStack(self._window, "onload", func, true); + + }, + + focusOnLoad: function (element) { + var self = MochiKit.DOM; + self.addLoadEvent(function () { + element = self.getElement(element); + if (element) { + element.focus(); + } + }); + }, + + setElementClass: function (element, className) { + var self = MochiKit.DOM; + var obj = self.getElement(element); + if (self.attributeArray.compliant) { + obj.setAttribute("class", className); + } else { + obj.setAttribute("className", className); + } + }, + + toggleElementClass: function (className/*, element... */) { + var self = MochiKit.DOM; + for (var i = 1; i < arguments.length; i++) { + var obj = self.getElement(arguments[i]); + if (!self.addElementClass(obj, className)) { + self.removeElementClass(obj, className); + } + } + }, + + addElementClass: function (element, className) { + var self = MochiKit.DOM; + var obj = self.getElement(element); + var cls = obj.className; + // trivial case, no className yet + if (cls.length === 0) { + self.setElementClass(obj, className); + return true; + } + // the other trivial case, already set as the only class + if (cls == className) { + return false; + } + var classes = obj.className.split(" "); + for (var i = 0; i < classes.length; i++) { + // already present + if (classes[i] == className) { + return false; + } + } + // append class + self.setElementClass(obj, cls + " " + className); + return true; + }, + + removeElementClass: function (element, className) { + var self = MochiKit.DOM; + var obj = self.getElement(element); + var cls = obj.className; + // trivial case, no className yet + if (cls.length === 0) { + return false; + } + // other trivial case, set only to className + if (cls == className) { + self.setElementClass(obj, ""); + return true; + } + var classes = obj.className.split(" "); + for (var i = 0; i < classes.length; i++) { + // already present + if (classes[i] == className) { + // only check sane case where the class is used once + classes.splice(i, 1); + self.setElementClass(obj, classes.join(" ")); + return true; + } + } + // not found + return false; + }, + + swapElementClass: function (element, fromClass, toClass) { + var obj = MochiKit.DOM.getElement(element); + var res = MochiKit.DOM.removeElementClass(obj, fromClass); + if (res) { + MochiKit.DOM.addElementClass(obj, toClass); + } + return res; + }, + + hasElementClass: function (element, className/*...*/) { + var obj = MochiKit.DOM.getElement(element); + var classes = obj.className.split(" "); + for (var i = 1; i < arguments.length; i++) { + var good = false; + for (var j = 0; j < classes.length; j++) { + if (classes[j] == arguments[i]) { + good = true; + break; + } + } + if (!good) { + return false; + } + } + return true; + }, + + escapeHTML: function (s) { + return s.replace(/&/g, "&" + ).replace(/"/g, """ + ).replace(//g, ">"); + }, + + toHTML: function (dom) { + return MochiKit.DOM.emitHTML(dom).join(""); + }, + + emitHTML: function (dom, /* optional */lst) { + if (typeof(lst) == 'undefined' || lst === null) { + lst = []; + } + // queue is the call stack, we're doing this non-recursively + var queue = [dom]; + var self = MochiKit.DOM; + var escapeHTML = self.escapeHTML; + var attributeArray = self.attributeArray; + while (queue.length) { + dom = queue.pop(); + if (typeof(dom) == 'string') { + lst.push(dom); + } else if (dom.nodeType == 1) { + // we're not using higher order stuff here + // because safari has heisenbugs.. argh. + // + // I think it might have something to do with + // garbage collection and function calls. + lst.push('<' + dom.nodeName.toLowerCase()); + var attributes = []; + var domAttr = attributeArray(dom); + for (var i = 0; i < domAttr.length; i++) { + var a = domAttr[i]; + attributes.push([ + " ", + a.name, + '="', + escapeHTML(a.value), + '"' + ]); + } + attributes.sort(); + for (i = 0; i < attributes.length; i++) { + var attrs = attributes[i]; + for (var j = 0; j < attrs.length; j++) { + lst.push(attrs[j]); + } + } + if (dom.hasChildNodes()) { + lst.push(">"); + // queue is the FILO call stack, so we put the close tag + // on first + queue.push(""); + var cnodes = dom.childNodes; + for (i = cnodes.length - 1; i >= 0; i--) { + queue.push(cnodes[i]); + } + } else { + lst.push('/>'); + } + } else if (dom.nodeType == 3) { + lst.push(escapeHTML(dom.nodeValue)); + } + } + return lst; + }, + + setDisplayForElement: function (display, element/*, ...*/) { + var m = MochiKit.Base; + var elements = m.extend(null, arguments, 1); + MochiKit.Iter.forEach( + m.filter(null, m.map(MochiKit.DOM.getElement, elements)), + function (element) { + element.style.display = display; + } + ); + }, + + scrapeText: function (node, /* optional */asArray) { + var rval = []; + (function (node) { + var cn = node.childNodes; + if (cn) { + for (var i = 0; i < cn.length; i++) { + arguments.callee.call(this, cn[i]); + } + } + var nodeValue = node.nodeValue; + if (typeof(nodeValue) == 'string') { + rval.push(nodeValue); + } + })(MochiKit.DOM.getElement(node)); + if (asArray) { + return rval; + } else { + return rval.join(""); + } + }, + + + __new__: function (win) { + + var m = MochiKit.Base; + this._document = document; + this._window = win; + + this.domConverters = new m.AdapterRegistry(); + + var __tmpElement = this._document.createElement("span"); + var attributeArray; + if (__tmpElement && __tmpElement.attributes && + __tmpElement.attributes.length > 0) { + // for braindead browsers (IE) that insert extra junk + var filter = m.filter; + attributeArray = function (node) { + return filter(attributeArray.ignoreAttrFilter, node.attributes); + }; + attributeArray.ignoreAttr = {}; + MochiKit.Iter.forEach(__tmpElement.attributes, function (a) { + attributeArray.ignoreAttr[a.name] = a.value; + }); + attributeArray.ignoreAttrFilter = function (a) { + return (attributeArray.ignoreAttr[a.name] != a.value); + }; + attributeArray.compliant = false; + attributeArray.renames = { + "class": "className", + "checked": "defaultChecked", + "usemap": "useMap", + "for": "htmlFor" + }; + } else { + attributeArray = function (node) { + /*** + + Return an array of attributes for a given node, + filtering out attributes that don't belong for + that are inserted by "Certain Browsers". + + ***/ + return node.attributes; + }; + attributeArray.compliant = true; + attributeArray.renames = {}; + } + this.attributeArray = attributeArray; + + + // shorthand for createDOM syntax + var createDOMFunc = this.createDOMFunc; + this.UL = createDOMFunc("ul"); + this.OL = createDOMFunc("ol"); + this.LI = createDOMFunc("li"); + this.TD = createDOMFunc("td"); + this.TR = createDOMFunc("tr"); + this.TBODY = createDOMFunc("tbody"); + this.THEAD = createDOMFunc("thead"); + this.TFOOT = createDOMFunc("tfoot"); + this.TABLE = createDOMFunc("table"); + this.TH = createDOMFunc("th"); + this.INPUT = createDOMFunc("input"); + this.SPAN = createDOMFunc("span"); + this.A = createDOMFunc("a"); + this.DIV = createDOMFunc("div"); + this.IMG = createDOMFunc("img"); + this.BUTTON = createDOMFunc("button"); + this.TT = createDOMFunc("tt"); + this.PRE = createDOMFunc("pre"); + this.H1 = createDOMFunc("h1"); + this.H2 = createDOMFunc("h2"); + this.H3 = createDOMFunc("h3"); + this.BR = createDOMFunc("br"); + this.HR = createDOMFunc("hr"); + this.LABEL = createDOMFunc("label"); + this.TEXTAREA = createDOMFunc("textarea"); + this.FORM = createDOMFunc("form"); + this.P = createDOMFunc("p"); + this.SELECT = createDOMFunc("select"); + this.OPTION = createDOMFunc("option"); + this.OPTGROUP = createDOMFunc("optgroup"); + this.LEGEND = createDOMFunc("legend"); + this.FIELDSET = createDOMFunc("fieldset"); + this.STRONG = createDOMFunc("strong"); + this.CANVAS = createDOMFunc("canvas"); + + this.hideElement = m.partial(this.setDisplayForElement, "none"); + this.showElement = m.partial(this.setDisplayForElement, "block"); + this.removeElement = this.swapDOM; + + this.$ = this.getElement; + + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": m.concat(this.EXPORT, this.EXPORT_OK) + }; + + m.nameFunctions(this); + + } +}); + +MochiKit.DOM.__new__(((typeof(window) == "undefined") ? this : window)); + +// +// XXX: Internet Explorer blows +// +if (!MochiKit.__compat__) { + withWindow = MochiKit.DOM.withWindow; + withDocument = MochiKit.DOM.withDocument; +} + +MochiKit.Base._exportSymbols(this, MochiKit.DOM); diff --git a/webtools/new-graph/js/mochikit/DateTime.js b/webtools/new-graph/js/mochikit/DateTime.js new file mode 100644 index 00000000000..b2d681a8207 --- /dev/null +++ b/webtools/new-graph/js/mochikit/DateTime.js @@ -0,0 +1,208 @@ +/*** + +MochiKit.DateTime 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.DateTime'); +} + +if (typeof(MochiKit) == 'undefined') { + MochiKit = {}; +} + +if (typeof(MochiKit.DateTime) == 'undefined') { + MochiKit.DateTime = {}; +} + +MochiKit.DateTime.NAME = "MochiKit.DateTime"; +MochiKit.DateTime.VERSION = "1.3.1"; +MochiKit.DateTime.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; +MochiKit.DateTime.toString = function () { + return this.__repr__(); +}; + +MochiKit.DateTime.isoDate = function (str) { + str = str + ""; + if (typeof(str) != "string" || str.length === 0) { + return null; + } + var iso = str.split('-'); + if (iso.length === 0) { + return null; + } + return new Date(iso[0], iso[1] - 1, iso[2]); +}; + +MochiKit.DateTime._isoRegexp = /(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/; + +MochiKit.DateTime.isoTimestamp = function (str) { + str = str + ""; + if (typeof(str) != "string" || str.length === 0) { + return null; + } + var res = str.match(MochiKit.DateTime._isoRegexp); + if (typeof(res) == "undefined" || res === null) { + return null; + } + var year, month, day, hour, min, sec, msec; + year = parseInt(res[1], 10); + if (typeof(res[2]) == "undefined" || res[2] === '') { + return new Date(year); + } + month = parseInt(res[2], 10) - 1; + day = parseInt(res[3], 10); + if (typeof(res[4]) == "undefined" || res[4] === '') { + return new Date(year, month, day); + } + hour = parseInt(res[4], 10); + min = parseInt(res[5], 10); + sec = (typeof(res[6]) != "undefined" && res[6] !== '') ? parseInt(res[6], 10) : 0; + if (typeof(res[7]) != "undefined" && res[7] !== '') { + msec = Math.round(1000.0 * parseFloat("0." + res[7])); + } else { + msec = 0; + } + if ((typeof(res[8]) == "undefined" || res[8] === '') && (typeof(res[9]) == "undefined" || res[9] === '')) { + return new Date(year, month, day, hour, min, sec, msec); + } + var ofs; + if (typeof(res[9]) != "undefined" && res[9] !== '') { + ofs = parseInt(res[10], 10) * 3600000; + if (typeof(res[11]) != "undefined" && res[11] !== '') { + ofs += parseInt(res[11], 10) * 60000; + } + if (res[9] == "-") { + ofs = -ofs; + } + } else { + ofs = 0; + } + return new Date(Date.UTC(year, month, day, hour, min, sec, msec) - ofs); +}; + +MochiKit.DateTime.toISOTime = function (date, realISO/* = false */) { + if (typeof(date) == "undefined" || date === null) { + return null; + } + var hh = date.getHours(); + var mm = date.getMinutes(); + var ss = date.getSeconds(); + var lst = [ + ((realISO && (hh < 10)) ? "0" + hh : hh), + ((mm < 10) ? "0" + mm : mm), + ((ss < 10) ? "0" + ss : ss) + ]; + return lst.join(":"); +}; + +MochiKit.DateTime.toISOTimestamp = function (date, realISO/* = false*/) { + if (typeof(date) == "undefined" || date === null) { + return null; + } + var sep = realISO ? "T" : " "; + var foot = realISO ? "Z" : ""; + if (realISO) { + date = new Date(date.getTime() + (date.getTimezoneOffset() * 60000)); + } + return MochiKit.DateTime.toISODate(date) + sep + MochiKit.DateTime.toISOTime(date, realISO) + foot; +}; + +MochiKit.DateTime.toISODate = function (date) { + if (typeof(date) == "undefined" || date === null) { + return null; + } + var _padTwo = MochiKit.DateTime._padTwo; + return [ + date.getFullYear(), + _padTwo(date.getMonth() + 1), + _padTwo(date.getDate()) + ].join("-"); +}; + +MochiKit.DateTime.americanDate = function (d) { + d = d + ""; + if (typeof(d) != "string" || d.length === 0) { + return null; + } + var a = d.split('/'); + return new Date(a[2], a[0] - 1, a[1]); +}; + +MochiKit.DateTime._padTwo = function (n) { + return (n > 9) ? n : "0" + n; +}; + +MochiKit.DateTime.toPaddedAmericanDate = function (d) { + if (typeof(d) == "undefined" || d === null) { + return null; + } + var _padTwo = MochiKit.DateTime._padTwo; + return [ + _padTwo(d.getMonth() + 1), + _padTwo(d.getDate()), + d.getFullYear() + ].join('/'); +}; + +MochiKit.DateTime.toAmericanDate = function (d) { + if (typeof(d) == "undefined" || d === null) { + return null; + } + return [d.getMonth() + 1, d.getDate(), d.getFullYear()].join('/'); +}; + +MochiKit.DateTime.EXPORT = [ + "isoDate", + "isoTimestamp", + "toISOTime", + "toISOTimestamp", + "toISODate", + "americanDate", + "toPaddedAmericanDate", + "toAmericanDate" +]; + +MochiKit.DateTime.EXPORT_OK = []; +MochiKit.DateTime.EXPORT_TAGS = { + ":common": MochiKit.DateTime.EXPORT, + ":all": MochiKit.DateTime.EXPORT +}; + +MochiKit.DateTime.__new__ = function () { + // MochiKit.Base.nameFunctions(this); + var base = this.NAME + "."; + for (var k in this) { + var o = this[k]; + if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') { + try { + o.NAME = base + k; + } catch (e) { + // pass + } + } + } +}; + +MochiKit.DateTime.__new__(); + +if (typeof(MochiKit.Base) != "undefined") { + MochiKit.Base._exportSymbols(this, MochiKit.DateTime); +} else { + (function (globals, module) { + if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined') + || (typeof(MochiKit.__compat__) == 'boolean' && MochiKit.__compat__)) { + var all = module.EXPORT_TAGS[":all"]; + for (var i = 0; i < all.length; i++) { + globals[all[i]] = module[all[i]]; + } + } + })(this, MochiKit.DateTime); +} diff --git a/webtools/new-graph/js/mochikit/Format.js b/webtools/new-graph/js/mochikit/Format.js new file mode 100644 index 00000000000..f835519484a --- /dev/null +++ b/webtools/new-graph/js/mochikit/Format.js @@ -0,0 +1,294 @@ +/*** + +MochiKit.Format 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.Format'); +} + +if (typeof(MochiKit) == 'undefined') { + MochiKit = {}; +} + +if (typeof(MochiKit.Format) == 'undefined') { + MochiKit.Format = {}; +} + +MochiKit.Format.NAME = "MochiKit.Format"; +MochiKit.Format.VERSION = "1.3.1"; +MochiKit.Format.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; +MochiKit.Format.toString = function () { + return this.__repr__(); +}; + +MochiKit.Format._numberFormatter = function (placeholder, header, footer, locale, isPercent, precision, leadingZeros, separatorAt, trailingZeros) { + return function (num) { + num = parseFloat(num); + if (typeof(num) == "undefined" || num === null || isNaN(num)) { + return placeholder; + } + var curheader = header; + var curfooter = footer; + if (num < 0) { + num = -num; + } else { + curheader = curheader.replace(/-/, ""); + } + var me = arguments.callee; + var fmt = MochiKit.Format.formatLocale(locale); + if (isPercent) { + num = num * 100.0; + curfooter = fmt.percent + curfooter; + } + num = MochiKit.Format.roundToFixed(num, precision); + var parts = num.split(/\./); + var whole = parts[0]; + var frac = (parts.length == 1) ? "" : parts[1]; + var res = ""; + while (whole.length < leadingZeros) { + whole = "0" + whole; + } + if (separatorAt) { + while (whole.length > separatorAt) { + var i = whole.length - separatorAt; + //res = res + fmt.separator + whole.substring(i, whole.length); + res = fmt.separator + whole.substring(i, whole.length) + res; + whole = whole.substring(0, i); + } + } + res = whole + res; + if (precision > 0) { + while (frac.length < trailingZeros) { + frac = frac + "0"; + } + res = res + fmt.decimal + frac; + } + return curheader + res + curfooter; + }; +}; + +MochiKit.Format.numberFormatter = function (pattern, placeholder/* = "" */, locale/* = "default" */) { + // http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html + // | 0 | leading or trailing zeros + // | # | just the number + // | , | separator + // | . | decimal separator + // | % | Multiply by 100 and format as percent + if (typeof(placeholder) == "undefined") { + placeholder = ""; + } + var match = pattern.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/); + if (!match) { + throw TypeError("Invalid pattern"); + } + var header = pattern.substr(0, match.index); + var footer = pattern.substr(match.index + match[0].length); + if (header.search(/-/) == -1) { + header = header + "-"; + } + var whole = match[1]; + var frac = (typeof(match[2]) == "string" && match[2] != "") ? match[2] : ""; + var isPercent = (typeof(match[3]) == "string" && match[3] != ""); + var tmp = whole.split(/,/); + var separatorAt; + if (typeof(locale) == "undefined") { + locale = "default"; + } + if (tmp.length == 1) { + separatorAt = null; + } else { + separatorAt = tmp[1].length; + } + var leadingZeros = whole.length - whole.replace(/0/g, "").length; + var trailingZeros = frac.length - frac.replace(/0/g, "").length; + var precision = frac.length; + var rval = MochiKit.Format._numberFormatter( + placeholder, header, footer, locale, isPercent, precision, + leadingZeros, separatorAt, trailingZeros + ); + var m = MochiKit.Base; + if (m) { + var fn = arguments.callee; + var args = m.concat(arguments); + rval.repr = function () { + return [ + self.NAME, + "(", + map(m.repr, args).join(", "), + ")" + ].join(""); + }; + } + return rval; +}; + +MochiKit.Format.formatLocale = function (locale) { + if (typeof(locale) == "undefined" || locale === null) { + locale = "default"; + } + if (typeof(locale) == "string") { + var rval = MochiKit.Format.LOCALE[locale]; + if (typeof(rval) == "string") { + rval = arguments.callee(rval); + MochiKit.Format.LOCALE[locale] = rval; + } + return rval; + } else { + return locale; + } +}; + +MochiKit.Format.twoDigitAverage = function (numerator, denominator) { + if (denominator) { + var res = numerator / denominator; + if (!isNaN(res)) { + return MochiKit.Format.twoDigitFloat(numerator / denominator); + } + } + return "0"; +}; + +MochiKit.Format.twoDigitFloat = function (someFloat) { + var sign = (someFloat < 0 ? '-' : ''); + var s = Math.floor(Math.abs(someFloat) * 100).toString(); + if (s == '0') { + return s; + } + if (s.length < 3) { + while (s.charAt(s.length - 1) == '0') { + s = s.substring(0, s.length - 1); + } + return sign + '0.' + s; + } + var head = sign + s.substring(0, s.length - 2); + var tail = s.substring(s.length - 2, s.length); + if (tail == '00') { + return head; + } else if (tail.charAt(1) == '0') { + return head + '.' + tail.charAt(0); + } else { + return head + '.' + tail; + } +}; + +MochiKit.Format.lstrip = function (str, /* optional */chars) { + str = str + ""; + if (typeof(str) != "string") { + return null; + } + if (!chars) { + return str.replace(/^\s+/, ""); + } else { + return str.replace(new RegExp("^[" + chars + "]+"), ""); + } +}; + +MochiKit.Format.rstrip = function (str, /* optional */chars) { + str = str + ""; + if (typeof(str) != "string") { + return null; + } + if (!chars) { + return str.replace(/\s+$/, ""); + } else { + return str.replace(new RegExp("[" + chars + "]+$"), ""); + } +}; + +MochiKit.Format.strip = function (str, /* optional */chars) { + var self = MochiKit.Format; + return self.rstrip(self.lstrip(str, chars), chars); +}; + +MochiKit.Format.truncToFixed = function (aNumber, precision) { + aNumber = Math.floor(aNumber * Math.pow(10, precision)); + var res = (aNumber * Math.pow(10, -precision)).toFixed(precision); + if (res.charAt(0) == ".") { + res = "0" + res; + } + return res; +}; + +MochiKit.Format.roundToFixed = function (aNumber, precision) { + return MochiKit.Format.truncToFixed( + aNumber + 0.5 * Math.pow(10, -precision), + precision + ); +}; + +MochiKit.Format.percentFormat = function (someFloat) { + return MochiKit.Format.twoDigitFloat(100 * someFloat) + '%'; +}; + +MochiKit.Format.EXPORT = [ + "truncToFixed", + "roundToFixed", + "numberFormatter", + "formatLocale", + "twoDigitAverage", + "twoDigitFloat", + "percentFormat", + "lstrip", + "rstrip", + "strip" +]; + +MochiKit.Format.LOCALE = { + en_US: {separator: ",", decimal: ".", percent: "%"}, + de_DE: {separator: ".", decimal: ",", percent: "%"}, + fr_FR: {separator: " ", decimal: ",", percent: "%"}, + "default": "en_US" +}; + +MochiKit.Format.EXPORT_OK = []; +MochiKit.Format.EXPORT_TAGS = { + ':all': MochiKit.Format.EXPORT, + ':common': MochiKit.Format.EXPORT +}; + +MochiKit.Format.__new__ = function () { + // MochiKit.Base.nameFunctions(this); + var base = this.NAME + "."; + var k, v, o; + for (k in this.LOCALE) { + o = this.LOCALE[k]; + if (typeof(o) == "object") { + o.repr = function () { return this.NAME; }; + o.NAME = base + "LOCALE." + k; + } + } + for (k in this) { + o = this[k]; + if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') { + try { + o.NAME = base + k; + } catch (e) { + // pass + } + } + } +}; + +MochiKit.Format.__new__(); + +if (typeof(MochiKit.Base) != "undefined") { + MochiKit.Base._exportSymbols(this, MochiKit.Format); +} else { + (function (globals, module) { + if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined') + || (typeof(MochiKit.__compat__) == 'boolean' && MochiKit.__compat__)) { + var all = module.EXPORT_TAGS[":all"]; + for (var i = 0; i < all.length; i++) { + globals[all[i]] = module[all[i]]; + } + } + })(this, MochiKit.Format); +} diff --git a/webtools/new-graph/js/mochikit/Iter.js b/webtools/new-graph/js/mochikit/Iter.js new file mode 100644 index 00000000000..138c79669da --- /dev/null +++ b/webtools/new-graph/js/mochikit/Iter.js @@ -0,0 +1,789 @@ +/*** + +MochiKit.Iter 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.Iter'); + dojo.require('MochiKit.Base'); +} + +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Base", []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.Iter depends on MochiKit.Base!"; +} + +if (typeof(MochiKit.Iter) == 'undefined') { + MochiKit.Iter = {}; +} + +MochiKit.Iter.NAME = "MochiKit.Iter"; +MochiKit.Iter.VERSION = "1.3.1"; +MochiKit.Base.update(MochiKit.Iter, { + __repr__: function () { + return "[" + this.NAME + " " + this.VERSION + "]"; + }, + toString: function () { + return this.__repr__(); + }, + + registerIteratorFactory: function (name, check, iterfactory, /* optional */ override) { + MochiKit.Iter.iteratorRegistry.register(name, check, iterfactory, override); + }, + + iter: function (iterable, /* optional */ sentinel) { + var self = MochiKit.Iter; + if (arguments.length == 2) { + return self.takewhile( + function (a) { return a != sentinel; }, + iterable + ); + } + if (typeof(iterable.next) == 'function') { + return iterable; + } else if (typeof(iterable.iter) == 'function') { + return iterable.iter(); + } + try { + return self.iteratorRegistry.match(iterable); + } catch (e) { + var m = MochiKit.Base; + if (e == m.NotFound) { + e = new TypeError(typeof(iterable) + ": " + m.repr(iterable) + " is not iterable"); + } + throw e; + } + }, + + count: function (n) { + if (!n) { + n = 0; + } + var m = MochiKit.Base; + return { + repr: function () { return "count(" + n + ")"; }, + toString: m.forwardCall("repr"), + next: m.counter(n) + }; + }, + + cycle: function (p) { + var self = MochiKit.Iter; + var m = MochiKit.Base; + var lst = []; + var iterator = self.iter(p); + return { + repr: function () { return "cycle(...)"; }, + toString: m.forwardCall("repr"), + next: function () { + try { + var rval = iterator.next(); + lst.push(rval); + return rval; + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + if (lst.length === 0) { + this.next = function () { + throw self.StopIteration; + }; + } else { + var i = -1; + this.next = function () { + i = (i + 1) % lst.length; + return lst[i]; + }; + } + return this.next(); + } + } + }; + }, + + repeat: function (elem, /* optional */n) { + var m = MochiKit.Base; + if (typeof(n) == 'undefined') { + return { + repr: function () { + return "repeat(" + m.repr(elem) + ")"; + }, + toString: m.forwardCall("repr"), + next: function () { + return elem; + } + }; + } + return { + repr: function () { + return "repeat(" + m.repr(elem) + ", " + n + ")"; + }, + toString: m.forwardCall("repr"), + next: function () { + if (n <= 0) { + throw MochiKit.Iter.StopIteration; + } + n -= 1; + return elem; + } + }; + }, + + next: function (iterator) { + return iterator.next(); + }, + + izip: function (p, q/*, ...*/) { + var m = MochiKit.Base; + var next = MochiKit.Iter.next; + var iterables = m.map(iter, arguments); + return { + repr: function () { return "izip(...)"; }, + toString: m.forwardCall("repr"), + next: function () { return m.map(next, iterables); } + }; + }, + + ifilter: function (pred, seq) { + var m = MochiKit.Base; + seq = MochiKit.Iter.iter(seq); + if (pred === null) { + pred = m.operator.truth; + } + return { + repr: function () { return "ifilter(...)"; }, + toString: m.forwardCall("repr"), + next: function () { + while (true) { + var rval = seq.next(); + if (pred(rval)) { + return rval; + } + } + // mozilla warnings aren't too bright + return undefined; + } + }; + }, + + ifilterfalse: function (pred, seq) { + var m = MochiKit.Base; + seq = MochiKit.Iter.iter(seq); + if (pred === null) { + pred = m.operator.truth; + } + return { + repr: function () { return "ifilterfalse(...)"; }, + toString: m.forwardCall("repr"), + next: function () { + while (true) { + var rval = seq.next(); + if (!pred(rval)) { + return rval; + } + } + // mozilla warnings aren't too bright + return undefined; + } + }; + }, + + islice: function (seq/*, [start,] stop[, step] */) { + var self = MochiKit.Iter; + var m = MochiKit.Base; + seq = self.iter(seq); + var start = 0; + var stop = 0; + var step = 1; + var i = -1; + if (arguments.length == 2) { + stop = arguments[1]; + } else if (arguments.length == 3) { + start = arguments[1]; + stop = arguments[2]; + } else { + start = arguments[1]; + stop = arguments[2]; + step = arguments[3]; + } + return { + repr: function () { + return "islice(" + ["...", start, stop, step].join(", ") + ")"; + }, + toString: m.forwardCall("repr"), + next: function () { + var rval; + while (i < start) { + rval = seq.next(); + i++; + } + if (start >= stop) { + throw self.StopIteration; + } + start += step; + return rval; + } + }; + }, + + imap: function (fun, p, q/*, ...*/) { + var m = MochiKit.Base; + var self = MochiKit.Iter; + var iterables = m.map(self.iter, m.extend(null, arguments, 1)); + var map = m.map; + var next = self.next; + return { + repr: function () { return "imap(...)"; }, + toString: m.forwardCall("repr"), + next: function () { + return fun.apply(this, map(next, iterables)); + } + }; + }, + + applymap: function (fun, seq, self) { + seq = MochiKit.Iter.iter(seq); + var m = MochiKit.Base; + return { + repr: function () { return "applymap(...)"; }, + toString: m.forwardCall("repr"), + next: function () { + return fun.apply(self, seq.next()); + } + }; + }, + + chain: function (p, q/*, ...*/) { + // dumb fast path + var self = MochiKit.Iter; + var m = MochiKit.Base; + if (arguments.length == 1) { + return self.iter(arguments[0]); + } + var argiter = m.map(self.iter, arguments); + return { + repr: function () { return "chain(...)"; }, + toString: m.forwardCall("repr"), + next: function () { + while (argiter.length > 1) { + try { + return argiter[0].next(); + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + argiter.shift(); + } + } + if (argiter.length == 1) { + // optimize last element + var arg = argiter.shift(); + this.next = m.bind("next", arg); + return this.next(); + } + throw self.StopIteration; + } + }; + }, + + takewhile: function (pred, seq) { + var self = MochiKit.Iter; + seq = self.iter(seq); + return { + repr: function () { return "takewhile(...)"; }, + toString: MochiKit.Base.forwardCall("repr"), + next: function () { + var rval = seq.next(); + if (!pred(rval)) { + this.next = function () { + throw self.StopIteration; + }; + this.next(); + } + return rval; + } + }; + }, + + dropwhile: function (pred, seq) { + seq = MochiKit.Iter.iter(seq); + var m = MochiKit.Base; + var bind = m.bind; + return { + "repr": function () { return "dropwhile(...)"; }, + "toString": m.forwardCall("repr"), + "next": function () { + while (true) { + var rval = seq.next(); + if (!pred(rval)) { + break; + } + } + this.next = bind("next", seq); + return rval; + } + }; + }, + + _tee: function (ident, sync, iterable) { + sync.pos[ident] = -1; + var m = MochiKit.Base; + var listMin = m.listMin; + return { + repr: function () { return "tee(" + ident + ", ...)"; }, + toString: m.forwardCall("repr"), + next: function () { + var rval; + var i = sync.pos[ident]; + + if (i == sync.max) { + rval = iterable.next(); + sync.deque.push(rval); + sync.max += 1; + sync.pos[ident] += 1; + } else { + rval = sync.deque[i - sync.min]; + sync.pos[ident] += 1; + if (i == sync.min && listMin(sync.pos) != sync.min) { + sync.min += 1; + sync.deque.shift(); + } + } + return rval; + } + }; + }, + + tee: function (iterable, n/* = 2 */) { + var rval = []; + var sync = { + "pos": [], + "deque": [], + "max": -1, + "min": -1 + }; + if (arguments.length == 1) { + n = 2; + } + var self = MochiKit.Iter; + iterable = self.iter(iterable); + var _tee = self._tee; + for (var i = 0; i < n; i++) { + rval.push(_tee(i, sync, iterable)); + } + return rval; + }, + + list: function (iterable) { + // Fast-path for Array and Array-like + var m = MochiKit.Base; + if (typeof(iterable.slice) == 'function') { + return iterable.slice(); + } else if (m.isArrayLike(iterable)) { + return m.concat(iterable); + } + + var self = MochiKit.Iter; + iterable = self.iter(iterable); + var rval = []; + try { + while (true) { + rval.push(iterable.next()); + } + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + return rval; + } + // mozilla warnings aren't too bright + return undefined; + }, + + + reduce: function (fn, iterable, /* optional */initial) { + var i = 0; + var x = initial; + var self = MochiKit.Iter; + iterable = self.iter(iterable); + if (arguments.length < 3) { + try { + x = iterable.next(); + } catch (e) { + if (e == self.StopIteration) { + e = new TypeError("reduce() of empty sequence with no initial value"); + } + throw e; + } + i++; + } + try { + while (true) { + x = fn(x, iterable.next()); + } + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + } + return x; + }, + + range: function (/* [start,] stop[, step] */) { + var start = 0; + var stop = 0; + var step = 1; + if (arguments.length == 1) { + stop = arguments[0]; + } else if (arguments.length == 2) { + start = arguments[0]; + stop = arguments[1]; + } else if (arguments.length == 3) { + start = arguments[0]; + stop = arguments[1]; + step = arguments[2]; + } else { + throw new TypeError("range() takes 1, 2, or 3 arguments!"); + } + if (step === 0) { + throw new TypeError("range() step must not be 0"); + } + return { + next: function () { + if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) { + throw MochiKit.Iter.StopIteration; + } + var rval = start; + start += step; + return rval; + }, + repr: function () { + return "range(" + [start, stop, step].join(", ") + ")"; + }, + toString: MochiKit.Base.forwardCall("repr") + }; + }, + + sum: function (iterable, start/* = 0 */) { + var x = start || 0; + var self = MochiKit.Iter; + iterable = self.iter(iterable); + try { + while (true) { + x += iterable.next(); + } + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + } + return x; + }, + + exhaust: function (iterable) { + var self = MochiKit.Iter; + iterable = self.iter(iterable); + try { + while (true) { + iterable.next(); + } + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + } + }, + + forEach: function (iterable, func, /* optional */self) { + var m = MochiKit.Base; + if (arguments.length > 2) { + func = m.bind(func, self); + } + // fast path for array + if (m.isArrayLike(iterable)) { + try { + for (var i = 0; i < iterable.length; i++) { + func(iterable[i]); + } + } catch (e) { + if (e != MochiKit.Iter.StopIteration) { + throw e; + } + } + } else { + self = MochiKit.Iter; + self.exhaust(self.imap(func, iterable)); + } + }, + + every: function (iterable, func) { + var self = MochiKit.Iter; + try { + self.ifilterfalse(func, iterable).next(); + return false; + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + return true; + } + }, + + sorted: function (iterable, /* optional */cmp) { + var rval = MochiKit.Iter.list(iterable); + if (arguments.length == 1) { + cmp = MochiKit.Base.compare; + } + rval.sort(cmp); + return rval; + }, + + reversed: function (iterable) { + var rval = MochiKit.Iter.list(iterable); + rval.reverse(); + return rval; + }, + + some: function (iterable, func) { + var self = MochiKit.Iter; + try { + self.ifilter(func, iterable).next(); + return true; + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + return false; + } + }, + + iextend: function (lst, iterable) { + if (MochiKit.Base.isArrayLike(iterable)) { + // fast-path for array-like + for (var i = 0; i < iterable.length; i++) { + lst.push(iterable[i]); + } + } else { + var self = MochiKit.Iter; + iterable = self.iter(iterable); + try { + while (true) { + lst.push(iterable.next()); + } + } catch (e) { + if (e != self.StopIteration) { + throw e; + } + } + } + return lst; + }, + + groupby: function(iterable, /* optional */ keyfunc) { + var m = MochiKit.Base; + var self = MochiKit.Iter; + if (arguments.length < 2) { + keyfunc = m.operator.identity; + } + iterable = self.iter(iterable); + + // shared + var pk = undefined; + var k = undefined; + var v; + + function fetch() { + v = iterable.next(); + k = keyfunc(v); + }; + + function eat() { + var ret = v; + v = undefined; + return ret; + }; + + var first = true; + return { + repr: function () { return "groupby(...)"; }, + next: function() { + // iterator-next + + // iterate until meet next group + while (k == pk) { + fetch(); + if (first) { + first = false; + break; + } + } + pk = k; + return [k, { + next: function() { + // subiterator-next + if (v == undefined) { // Is there something to eat? + fetch(); + } + if (k != pk) { + throw self.StopIteration; + } + return eat(); + } + }]; + } + }; + }, + + groupby_as_array: function (iterable, /* optional */ keyfunc) { + var m = MochiKit.Base; + var self = MochiKit.Iter; + if (arguments.length < 2) { + keyfunc = m.operator.identity; + } + + iterable = self.iter(iterable); + var result = []; + var first = true; + var prev_key; + while (true) { + try { + var value = iterable.next(); + var key = keyfunc(value); + } catch (e) { + if (e == self.StopIteration) { + break; + } + throw e; + } + if (first || key != prev_key) { + var values = []; + result.push([key, values]); + } + values.push(value); + first = false; + prev_key = key; + } + return result; + }, + + arrayLikeIter: function (iterable) { + var i = 0; + return { + repr: function () { return "arrayLikeIter(...)"; }, + toString: MochiKit.Base.forwardCall("repr"), + next: function () { + if (i >= iterable.length) { + throw MochiKit.Iter.StopIteration; + } + return iterable[i++]; + } + }; + }, + + hasIterateNext: function (iterable) { + return (iterable && typeof(iterable.iterateNext) == "function"); + }, + + iterateNextIter: function (iterable) { + return { + repr: function () { return "iterateNextIter(...)"; }, + toString: MochiKit.Base.forwardCall("repr"), + next: function () { + var rval = iterable.iterateNext(); + if (rval === null || rval === undefined) { + throw MochiKit.Iter.StopIteration; + } + return rval; + } + }; + } +}); + + +MochiKit.Iter.EXPORT_OK = [ + "iteratorRegistry", + "arrayLikeIter", + "hasIterateNext", + "iterateNextIter", +]; + +MochiKit.Iter.EXPORT = [ + "StopIteration", + "registerIteratorFactory", + "iter", + "count", + "cycle", + "repeat", + "next", + "izip", + "ifilter", + "ifilterfalse", + "islice", + "imap", + "applymap", + "chain", + "takewhile", + "dropwhile", + "tee", + "list", + "reduce", + "range", + "sum", + "exhaust", + "forEach", + "every", + "sorted", + "reversed", + "some", + "iextend", + "groupby", + "groupby_as_array" +]; + +MochiKit.Iter.__new__ = function () { + var m = MochiKit.Base; + this.StopIteration = new m.NamedError("StopIteration"); + this.iteratorRegistry = new m.AdapterRegistry(); + // Register the iterator factory for arrays + this.registerIteratorFactory( + "arrayLike", + m.isArrayLike, + this.arrayLikeIter + ); + + this.registerIteratorFactory( + "iterateNext", + this.hasIterateNext, + this.iterateNextIter + ); + + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": m.concat(this.EXPORT, this.EXPORT_OK) + }; + + m.nameFunctions(this); + +}; + +MochiKit.Iter.__new__(); + +// +// XXX: Internet Explorer blows +// +if (!MochiKit.__compat__) { + reduce = MochiKit.Iter.reduce; +} + +MochiKit.Base._exportSymbols(this, MochiKit.Iter); diff --git a/webtools/new-graph/js/mochikit/Logging.js b/webtools/new-graph/js/mochikit/Logging.js new file mode 100644 index 00000000000..c7a0ac5fc8c --- /dev/null +++ b/webtools/new-graph/js/mochikit/Logging.js @@ -0,0 +1,290 @@ +/*** + +MochiKit.Logging 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.Logging'); + dojo.require('MochiKit.Base'); +} + +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Base", []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.Logging depends on MochiKit.Base!"; +} + +if (typeof(MochiKit.Logging) == 'undefined') { + MochiKit.Logging = {}; +} + +MochiKit.Logging.NAME = "MochiKit.Logging"; +MochiKit.Logging.VERSION = "1.3.1"; +MochiKit.Logging.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; + +MochiKit.Logging.toString = function () { + return this.__repr__(); +}; + + +MochiKit.Logging.EXPORT = [ + "LogLevel", + "LogMessage", + "Logger", + "alertListener", + "logger", + "log", + "logError", + "logDebug", + "logFatal", + "logWarning" +]; + + +MochiKit.Logging.EXPORT_OK = [ + "logLevelAtLeast", + "isLogMessage", + "compareLogMessage" +]; + + +MochiKit.Logging.LogMessage = function (num, level, info) { + this.num = num; + this.level = level; + this.info = info; + this.timestamp = new Date(); +}; + +MochiKit.Logging.LogMessage.prototype = { + repr: function () { + var m = MochiKit.Base; + return 'LogMessage(' + + m.map( + m.repr, + [this.num, this.level, this.info] + ).join(', ') + ')'; + }, + toString: MochiKit.Base.forwardCall("repr") +}; + +MochiKit.Base.update(MochiKit.Logging, { + logLevelAtLeast: function (minLevel) { + var self = MochiKit.Logging; + if (typeof(minLevel) == 'string') { + minLevel = self.LogLevel[minLevel]; + } + return function (msg) { + var msgLevel = msg.level; + if (typeof(msgLevel) == 'string') { + msgLevel = self.LogLevel[msgLevel]; + } + return msgLevel >= minLevel; + }; + }, + + isLogMessage: function (/* ... */) { + var LogMessage = MochiKit.Logging.LogMessage; + for (var i = 0; i < arguments.length; i++) { + if (!(arguments[i] instanceof LogMessage)) { + return false; + } + } + return true; + }, + + compareLogMessage: function (a, b) { + return MochiKit.Base.compare([a.level, a.info], [b.level, b.info]); + }, + + alertListener: function (msg) { + alert( + "num: " + msg.num + + "\nlevel: " + msg.level + + "\ninfo: " + msg.info.join(" ") + ); + } + +}); + +MochiKit.Logging.Logger = function (/* optional */maxSize) { + this.counter = 0; + if (typeof(maxSize) == 'undefined' || maxSize === null) { + maxSize = -1; + } + this.maxSize = maxSize; + this._messages = []; + this.listeners = {}; + this.useNativeConsole = false; +}; + +MochiKit.Logging.Logger.prototype = { + clear: function () { + this._messages.splice(0, this._messages.length); + }, + + logToConsole: function (msg) { + if (typeof(window) != "undefined" && window.console + && window.console.log) { + // Safari + window.console.log(msg); + } else if (typeof(opera) != "undefined" && opera.postError) { + // Opera + opera.postError(msg); + } else if (typeof(printfire) == "function") { + // FireBug + printfire(msg); + } + }, + + dispatchListeners: function (msg) { + for (var k in this.listeners) { + var pair = this.listeners[k]; + if (pair.ident != k || (pair[0] && !pair[0](msg))) { + continue; + } + pair[1](msg); + } + }, + + addListener: function (ident, filter, listener) { + if (typeof(filter) == 'string') { + filter = MochiKit.Logging.logLevelAtLeast(filter); + } + var entry = [filter, listener]; + entry.ident = ident; + this.listeners[ident] = entry; + }, + + removeListener: function (ident) { + delete this.listeners[ident]; + }, + + baseLog: function (level, message/*, ...*/) { + var msg = new MochiKit.Logging.LogMessage( + this.counter, + level, + MochiKit.Base.extend(null, arguments, 1) + ); + this._messages.push(msg); + this.dispatchListeners(msg); + if (this.useNativeConsole) { + this.logToConsole(msg.level + ": " + msg.info.join(" ")); + } + this.counter += 1; + while (this.maxSize >= 0 && this._messages.length > this.maxSize) { + this._messages.shift(); + } + }, + + getMessages: function (howMany) { + var firstMsg = 0; + if (!(typeof(howMany) == 'undefined' || howMany === null)) { + firstMsg = Math.max(0, this._messages.length - howMany); + } + return this._messages.slice(firstMsg); + }, + + getMessageText: function (howMany) { + if (typeof(howMany) == 'undefined' || howMany === null) { + howMany = 30; + } + var messages = this.getMessages(howMany); + if (messages.length) { + var lst = map(function (m) { + return '\n [' + m.num + '] ' + m.level + ': ' + m.info.join(' '); + }, messages); + lst.unshift('LAST ' + messages.length + ' MESSAGES:'); + return lst.join(''); + } + return ''; + }, + + debuggingBookmarklet: function (inline) { + if (typeof(MochiKit.LoggingPane) == "undefined") { + alert(this.getMessageText()); + } else { + MochiKit.LoggingPane.createLoggingPane(inline || false); + } + } +}; + + +MochiKit.Logging.__new__ = function () { + this.LogLevel = { + ERROR: 40, + FATAL: 50, + WARNING: 30, + INFO: 20, + DEBUG: 10 + }; + + var m = MochiKit.Base; + m.registerComparator("LogMessage", + this.isLogMessage, + this.compareLogMessage + ); + + var partial = m.partial; + + var Logger = this.Logger; + var baseLog = Logger.prototype.baseLog; + m.update(this.Logger.prototype, { + debug: partial(baseLog, 'DEBUG'), + log: partial(baseLog, 'INFO'), + error: partial(baseLog, 'ERROR'), + fatal: partial(baseLog, 'FATAL'), + warning: partial(baseLog, 'WARNING') + }); + + // indirectly find logger so it can be replaced + var self = this; + var connectLog = function (name) { + return function () { + self.logger[name].apply(self.logger, arguments); + }; + }; + + this.log = connectLog('log'); + this.logError = connectLog('error'); + this.logDebug = connectLog('debug'); + this.logFatal = connectLog('fatal'); + this.logWarning = connectLog('warning'); + this.logger = new Logger(); + this.logger.useNativeConsole = true; + + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": m.concat(this.EXPORT, this.EXPORT_OK) + }; + + m.nameFunctions(this); + +}; + +if (typeof(printfire) == "undefined" && + typeof(document) != "undefined" && document.createEvent && + typeof(dispatchEvent) != "undefined") { + // FireBug really should be less lame about this global function + printfire = function () { + printfire.args = arguments; + var ev = document.createEvent("Events"); + ev.initEvent("printfire", false, true); + dispatchEvent(ev); + }; +} + +MochiKit.Logging.__new__(); + +MochiKit.Base._exportSymbols(this, MochiKit.Logging); diff --git a/webtools/new-graph/js/mochikit/LoggingPane.js b/webtools/new-graph/js/mochikit/LoggingPane.js new file mode 100644 index 00000000000..5705681b7f6 --- /dev/null +++ b/webtools/new-graph/js/mochikit/LoggingPane.js @@ -0,0 +1,356 @@ +/*** + +MochiKit.LoggingPane 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.LoggingPane'); + dojo.require('MochiKit.Logging'); + dojo.require('MochiKit.Base'); +} + +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Logging", []); + JSAN.use("MochiKit.Base", []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined' || typeof(MochiKit.Logging) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.LoggingPane depends on MochiKit.Base and MochiKit.Logging!"; +} + +if (typeof(MochiKit.LoggingPane) == 'undefined') { + MochiKit.LoggingPane = {}; +} + +MochiKit.LoggingPane.NAME = "MochiKit.LoggingPane"; +MochiKit.LoggingPane.VERSION = "1.3.1"; +MochiKit.LoggingPane.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; + +MochiKit.LoggingPane.toString = function () { + return this.__repr__(); +}; + +MochiKit.LoggingPane.createLoggingPane = function (inline/* = false */) { + var m = MochiKit.LoggingPane; + inline = !(!inline); + if (m._loggingPane && m._loggingPane.inline != inline) { + m._loggingPane.closePane(); + m._loggingPane = null; + } + if (!m._loggingPane || m._loggingPane.closed) { + m._loggingPane = new m.LoggingPane(inline, MochiKit.Logging.logger); + } + return m._loggingPane; +}; + +MochiKit.LoggingPane.LoggingPane = function (inline/* = false */, logger/* = MochiKit.Logging.logger */) { + /* Use a div if inline, pop up a window if not */ + /* Create the elements */ + if (typeof(logger) == "undefined" || logger === null) { + logger = MochiKit.Logging.logger; + } + this.logger = logger; + var update = MochiKit.Base.update; + var updatetree = MochiKit.Base.updatetree; + var bind = MochiKit.Base.bind; + var clone = MochiKit.Base.clone; + var win = window; + var uid = "_MochiKit_LoggingPane"; + if (typeof(MochiKit.DOM) != "undefined") { + win = MochiKit.DOM.currentWindow(); + } + if (!inline) { + // name the popup with the base URL for uniqueness + var url = win.location.href.split("?")[0].replace(/[:\/.><&]/g, "_"); + var name = uid + "_" + url; + var nwin = win.open("", name, "dependent,resizable,height=200"); + if (!nwin) { + alert("Not able to open debugging window due to pop-up blocking."); + return undefined; + } + nwin.document.write( + '' + + '[MochiKit.LoggingPane]' + + '' + ); + nwin.document.close(); + nwin.document.title += ' ' + win.document.title; + win = nwin; + } + var doc = win.document; + this.doc = doc; + + // Connect to the debug pane if it already exists (i.e. in a window orphaned by the page being refreshed) + var debugPane = doc.getElementById(uid); + var existing_pane = !!debugPane; + if (debugPane && typeof(debugPane.loggingPane) != "undefined") { + debugPane.loggingPane.logger = this.logger; + debugPane.loggingPane.buildAndApplyFilter(); + return debugPane.loggingPane; + } + + if (existing_pane) { + // clear any existing contents + var child; + while ((child = debugPane.firstChild)) { + debugPane.removeChild(child); + } + } else { + debugPane = doc.createElement("div"); + debugPane.id = uid; + } + debugPane.loggingPane = this; + var levelFilterField = doc.createElement("input"); + var infoFilterField = doc.createElement("input"); + var filterButton = doc.createElement("button"); + var loadButton = doc.createElement("button"); + var clearButton = doc.createElement("button"); + var closeButton = doc.createElement("button"); + var logPaneArea = doc.createElement("div"); + var logPane = doc.createElement("div"); + + /* Set up the functions */ + var listenerId = uid + "_Listener"; + this.colorTable = clone(this.colorTable); + var messages = []; + var messageFilter = null; + + var messageLevel = function (msg) { + var level = msg.level; + if (typeof(level) == "number") { + level = MochiKit.Logging.LogLevel[level]; + } + return level; + }; + + var messageText = function (msg) { + return msg.info.join(" "); + }; + + var addMessageText = bind(function (msg) { + var level = messageLevel(msg); + var text = messageText(msg); + var c = this.colorTable[level]; + var p = doc.createElement("span"); + p.className = "MochiKit-LogMessage MochiKit-LogLevel-" + level; + p.style.cssText = "margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: " + c; + p.appendChild(doc.createTextNode(level + ": " + text)); + logPane.appendChild(p); + logPane.appendChild(doc.createElement("br")); + if (logPaneArea.offsetHeight > logPaneArea.scrollHeight) { + logPaneArea.scrollTop = 0; + } else { + logPaneArea.scrollTop = logPaneArea.scrollHeight; + } + }, this); + + var addMessage = function (msg) { + messages[messages.length] = msg; + addMessageText(msg); + }; + + var buildMessageFilter = function () { + var levelre, infore; + try { + /* Catch any exceptions that might arise due to invalid regexes */ + levelre = new RegExp(levelFilterField.value); + infore = new RegExp(infoFilterField.value); + } catch(e) { + /* If there was an error with the regexes, do no filtering */ + logDebug("Error in filter regex: " + e.message); + return null; + } + + return function (msg) { + return ( + levelre.test(messageLevel(msg)) && + infore.test(messageText(msg)) + ); + }; + }; + + var clearMessagePane = function () { + while (logPane.firstChild) { + logPane.removeChild(logPane.firstChild); + } + }; + + var clearMessages = function () { + messages = []; + clearMessagePane(); + }; + + var closePane = bind(function () { + if (this.closed) { + return; + } + this.closed = true; + if (MochiKit.LoggingPane._loggingPane == this) { + MochiKit.LoggingPane._loggingPane = null; + } + this.logger.removeListener(listenerId); + + debugPane.loggingPane = null; + + if (inline) { + debugPane.parentNode.removeChild(debugPane); + } else { + this.win.close(); + } + }, this); + + var filterMessages = function () { + clearMessagePane(); + + for (var i = 0; i < messages.length; i++) { + var msg = messages[i]; + if (messageFilter === null || messageFilter(msg)) { + addMessageText(msg); + } + } + }; + + this.buildAndApplyFilter = function () { + messageFilter = buildMessageFilter(); + + filterMessages(); + + this.logger.removeListener(listenerId); + this.logger.addListener(listenerId, messageFilter, addMessage); + }; + + + var loadMessages = bind(function () { + messages = this.logger.getMessages(); + filterMessages(); + }, this); + + var filterOnEnter = bind(function (event) { + event = event || window.event; + key = event.which || event.keyCode; + if (key == 13) { + this.buildAndApplyFilter(); + } + }, this); + + /* Create the debug pane */ + var style = "display: block; z-index: 1000; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: " + this.logFont; + if (inline) { + style += "; height: 10em; border-top: 2px solid black"; + } else { + style += "; height: 100%;"; + } + debugPane.style.cssText = style; + + if (!existing_pane) { + doc.body.appendChild(debugPane); + } + + /* Create the filter fields */ + style = {"cssText": "width: 33%; display: inline; font: " + this.logFont}; + + updatetree(levelFilterField, { + "value": "FATAL|ERROR|WARNING|INFO|DEBUG", + "onkeypress": filterOnEnter, + "style": style + }); + debugPane.appendChild(levelFilterField); + + updatetree(infoFilterField, { + "value": ".*", + "onkeypress": filterOnEnter, + "style": style + }); + debugPane.appendChild(infoFilterField); + + /* Create the buttons */ + style = "width: 8%; display:inline; font: " + this.logFont; + + filterButton.appendChild(doc.createTextNode("Filter")); + filterButton.onclick = bind("buildAndApplyFilter", this); + filterButton.style.cssText = style; + debugPane.appendChild(filterButton); + + loadButton.appendChild(doc.createTextNode("Load")); + loadButton.onclick = loadMessages; + loadButton.style.cssText = style; + debugPane.appendChild(loadButton); + + clearButton.appendChild(doc.createTextNode("Clear")); + clearButton.onclick = clearMessages; + clearButton.style.cssText = style; + debugPane.appendChild(clearButton); + + closeButton.appendChild(doc.createTextNode("Close")); + closeButton.onclick = closePane; + closeButton.style.cssText = style; + debugPane.appendChild(closeButton); + + /* Create the logging pane */ + logPaneArea.style.cssText = "overflow: auto; width: 100%"; + logPane.style.cssText = "width: 100%; height: " + (inline ? "8em" : "100%"); + + logPaneArea.appendChild(logPane); + debugPane.appendChild(logPaneArea); + + this.buildAndApplyFilter(); + loadMessages(); + + if (inline) { + this.win = undefined; + } else { + this.win = win; + } + this.inline = inline; + this.closePane = closePane; + this.closed = false; + + return this; +}; + +MochiKit.LoggingPane.LoggingPane.prototype = { + "logFont": "8pt Verdana,sans-serif", + "colorTable": { + "ERROR": "red", + "FATAL": "darkred", + "WARNING": "blue", + "INFO": "black", + "DEBUG": "green" + } +}; + + +MochiKit.LoggingPane.EXPORT_OK = [ + "LoggingPane" +]; + +MochiKit.LoggingPane.EXPORT = [ + "createLoggingPane" +]; + +MochiKit.LoggingPane.__new__ = function () { + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": MochiKit.Base.concat(this.EXPORT, this.EXPORT_OK) + }; + + MochiKit.Base.nameFunctions(this); + + MochiKit.LoggingPane._loggingPane = null; + +}; + +MochiKit.LoggingPane.__new__(); + +MochiKit.Base._exportSymbols(this, MochiKit.LoggingPane); diff --git a/webtools/new-graph/js/mochikit/MochiKit.js b/webtools/new-graph/js/mochikit/MochiKit.js new file mode 100644 index 00000000000..31307687dc6 --- /dev/null +++ b/webtools/new-graph/js/mochikit/MochiKit.js @@ -0,0 +1,152 @@ +/*** + +MochiKit.MochiKit 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(MochiKit) == 'undefined') { + MochiKit = {}; +} + +if (typeof(MochiKit.MochiKit) == 'undefined') { + MochiKit.MochiKit = {}; +} + +MochiKit.MochiKit.NAME = "MochiKit.MochiKit"; +MochiKit.MochiKit.VERSION = "1.3.1"; +MochiKit.MochiKit.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; + +MochiKit.MochiKit.toString = function () { + return this.__repr__(); +}; + +MochiKit.MochiKit.SUBMODULES = [ + "Base", + "Iter", + "Logging", + "DateTime", + "Format", + "Async", + "DOM", + "LoggingPane", + "Color", + "Signal", + "Visual" +]; + +if (typeof(JSAN) != 'undefined' || typeof(dojo) != 'undefined') { + if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.MochiKit'); + dojo.require("MochiKit.*"); + } + if (typeof(JSAN) != 'undefined') { + // hopefully this makes it easier for static analysis? + JSAN.use("MochiKit.Base", []); + JSAN.use("MochiKit.Iter", []); + JSAN.use("MochiKit.Logging", []); + JSAN.use("MochiKit.DateTime", []); + JSAN.use("MochiKit.Format", []); + JSAN.use("MochiKit.Async", []); + JSAN.use("MochiKit.DOM", []); + JSAN.use("MochiKit.LoggingPane", []); + JSAN.use("MochiKit.Color", []); + JSAN.use("MochiKit.Signal", []); + JSAN.use("MochiKit.Visual", []); + } + (function () { + var extend = MochiKit.Base.extend; + var self = MochiKit.MochiKit; + var modules = self.SUBMODULES; + var EXPORT = []; + var EXPORT_OK = []; + var EXPORT_TAGS = {}; + var i, k, m, all; + for (i = 0; i < modules.length; i++) { + m = MochiKit[modules[i]]; + extend(EXPORT, m.EXPORT); + extend(EXPORT_OK, m.EXPORT_OK); + for (k in m.EXPORT_TAGS) { + EXPORT_TAGS[k] = extend(EXPORT_TAGS[k], m.EXPORT_TAGS[k]); + } + all = m.EXPORT_TAGS[":all"]; + if (!all) { + all = extend(null, m.EXPORT, m.EXPORT_OK); + } + var j; + for (j = 0; j < all.length; j++) { + k = all[j]; + self[k] = m[k]; + } + } + self.EXPORT = EXPORT; + self.EXPORT_OK = EXPORT_OK; + self.EXPORT_TAGS = EXPORT_TAGS; + }()); + +} else { + if (typeof(MochiKit.__compat__) == 'undefined') { + MochiKit.__compat__ = true; + } + (function () { + var scripts = document.getElementsByTagName("script"); + var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + var base = null; + var baseElem = null; + var allScripts = {}; + var i; + for (i = 0; i < scripts.length; i++) { + var src = scripts[i].getAttribute("src"); + if (!src) { + continue; + } + allScripts[src] = true; + if (src.match(/MochiKit.js$/)) { + base = src.substring(0, src.lastIndexOf('MochiKit.js')); + baseElem = scripts[i]; + } + } + if (base === null) { + return; + } + var modules = MochiKit.MochiKit.SUBMODULES; + for (var i = 0; i < modules.length; i++) { + if (MochiKit[modules[i]]) { + continue; + } + var uri = base + modules[i] + '.js'; + if (uri in allScripts) { + continue; + } + if (document.documentElement && + document.documentElement.namespaceURI == kXULNSURI) { + // XUL + var s = document.createElementNS(kXULNSURI, 'script'); + s.setAttribute("id", "MochiKit_" + base + modules[i]); + s.setAttribute("src", uri); + s.setAttribute("type", "application/x-javascript"); + baseElem.parentNode.appendChild(s); + } else { + // HTML + /* + DOM can not be used here because Safari does + deferred loading of scripts unless they are + in the document or inserted with document.write + + This is not XHTML compliant. If you want XHTML + compliance then you must use the packed version of MochiKit + or include each script individually (basically unroll + these document.write calls into your XHTML source) + + */ + document.write(''); + } + }; + })(); +} diff --git a/webtools/new-graph/js/mochikit/MockDOM.js b/webtools/new-graph/js/mochikit/MockDOM.js new file mode 100644 index 00000000000..471ef051a69 --- /dev/null +++ b/webtools/new-graph/js/mochikit/MockDOM.js @@ -0,0 +1,73 @@ +/*** + +MochiKit.MockDOM 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ +if (typeof(MochiKit) == "undefined") { + var MochiKit = {}; +} + +if (typeof(MochiKit.MockDOM) == "undefined") { + MochiKit.MockDOM = {}; +} + +MochiKit.MockDOM.NAME = "MochiKit.MockDOM"; +MochiKit.MockDOM.VERSION = "1.3.1"; + +MochiKit.MockDOM.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; + +MochiKit.MockDOM.toString = function () { + return this.__repr__(); +}; + +MochiKit.MockDOM.createDocument = function () { + var doc = new MochiKit.MockDOM.MockElement("DOCUMENT"); + doc.body = doc.createElement("BODY"); + doc.appendChild(doc.body); + return doc; +}; + +MochiKit.MockDOM.MockElement = function (name, data) { + this.nodeName = name.toUpperCase(); + if (typeof(data) == "string") { + this.nodeValue = data; + this.nodeType = 3; + } else { + this.nodeType = 1; + this.childNodes = []; + } + if (name.substring(0, 1) == "<") { + var nameattr = name.substring( + name.indexOf('"') + 1, name.lastIndexOf('"')); + name = name.substring(1, name.indexOf(" ")); + this.nodeName = name.toUpperCase(); + this.setAttribute("name", nameattr); + } +}; + +MochiKit.MockDOM.MockElement.prototype = { + createElement: function (nodeName) { + return new MochiKit.MockDOM.MockElement(nodeName); + }, + createTextNode: function (text) { + return new MochiKit.MockDOM.MockElement("text", text); + }, + setAttribute: function (name, value) { + this[name] = value; + }, + getAttribute: function (name) { + return this[name]; + }, + appendChild: function (child) { + this.childNodes.push(child); + }, + toString: function () { + return "MockElement(" + this.nodeName + ")"; + } +}; diff --git a/webtools/new-graph/js/mochikit/Signal.js b/webtools/new-graph/js/mochikit/Signal.js new file mode 100644 index 00000000000..5624b3deb26 --- /dev/null +++ b/webtools/new-graph/js/mochikit/Signal.js @@ -0,0 +1,680 @@ +/*** + +MochiKit.Signal 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2006 Jonathan Gardner, Beau Hartshorne, Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.Signal'); + dojo.require('MochiKit.Base'); + dojo.require('MochiKit.DOM'); +} +if (typeof(JSAN) != 'undefined') { + JSAN.use('MochiKit.Base', []); + JSAN.use('MochiKit.DOM', []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined') { + throw ''; + } +} catch (e) { + throw 'MochiKit.Signal depends on MochiKit.Base!'; +} + +try { + if (typeof(MochiKit.DOM) == 'undefined') { + throw ''; + } +} catch (e) { + throw 'MochiKit.Signal depends on MochiKit.DOM!'; +} + +if (typeof(MochiKit.Signal) == 'undefined') { + MochiKit.Signal = {}; +} + +MochiKit.Signal.NAME = 'MochiKit.Signal'; +MochiKit.Signal.VERSION = '1.3.1'; + +MochiKit.Signal._observers = []; + +MochiKit.Signal.Event = function (src, e) { + this._event = e || window.event; + this._src = src; +}; + +MochiKit.Base.update(MochiKit.Signal.Event.prototype, { + + __repr__: function() { + var repr = MochiKit.Base.repr; + var str = '{event(): ' + repr(this.event()) + + ', src(): ' + repr(this.src()) + + ', type(): ' + repr(this.type()) + + ', target(): ' + repr(this.target()) + + ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) + + ', ctrl: ' + repr(this.modifier().ctrl) + + ', meta: ' + repr(this.modifier().meta) + + ', shift: ' + repr(this.modifier().shift) + + ', any: ' + repr(this.modifier().any) + '}'; + + if (this.type() && this.type().indexOf('key') === 0) { + str += ', key(): {code: ' + repr(this.key().code) + + ', string: ' + repr(this.key().string) + '}'; + } + + if (this.type() && ( + this.type().indexOf('mouse') === 0 || + this.type().indexOf('click') != -1 || + this.type() == 'contextmenu')) { + + str += ', mouse(): {page: ' + repr(this.mouse().page) + + ', client: ' + repr(this.mouse().client); + + if (this.type() != 'mousemove') { + str += ', button: {left: ' + repr(this.mouse().button.left) + + ', middle: ' + repr(this.mouse().button.middle) + + ', right: ' + repr(this.mouse().button.right) + '}}'; + } else { + str += '}'; + } + } + if (this.type() == 'mouseover' || this.type() == 'mouseout') { + str += ', relatedTarget(): ' + repr(this.relatedTarget()); + } + str += '}'; + return str; + }, + + toString: function () { + return this.__repr__(); + }, + + src: function () { + return this._src; + }, + + event: function () { + return this._event; + }, + + type: function () { + return this._event.type || undefined; + }, + + target: function () { + return this._event.target || this._event.srcElement; + }, + + relatedTarget: function () { + if (this.type() == 'mouseover') { + return (this._event.relatedTarget || + this._event.fromElement); + } else if (this.type() == 'mouseout') { + return (this._event.relatedTarget || + this._event.toElement); + } + // throw new Error("relatedTarget only available for 'mouseover' and 'mouseout'"); + return undefined; + }, + + modifier: function () { + var m = {}; + m.alt = this._event.altKey; + m.ctrl = this._event.ctrlKey; + m.meta = this._event.metaKey || false; // IE and Opera punt here + m.shift = this._event.shiftKey; + m.any = m.alt || m.ctrl || m.shift || m.meta; + return m; + }, + + key: function () { + var k = {}; + if (this.type() && this.type().indexOf('key') === 0) { + + /* + + If you're looking for a special key, look for it in keydown or + keyup, but never keypress. If you're looking for a Unicode + chracter, look for it with keypress, but never keyup or + keydown. + + Notes: + + FF key event behavior: + key event charCode keyCode + DOWN ku,kd 0 40 + DOWN kp 0 40 + ESC ku,kd 0 27 + ESC kp 0 27 + a ku,kd 0 65 + a kp 97 0 + shift+a ku,kd 0 65 + shift+a kp 65 0 + 1 ku,kd 0 49 + 1 kp 49 0 + shift+1 ku,kd 0 0 + shift+1 kp 33 0 + + IE key event behavior: + (IE doesn't fire keypress events for special keys.) + key event keyCode + DOWN ku,kd 40 + DOWN kp undefined + ESC ku,kd 27 + ESC kp 27 + a ku,kd 65 + a kp 97 + shift+a ku,kd 65 + shift+a kp 65 + 1 ku,kd 49 + 1 kp 49 + shift+1 ku,kd 49 + shift+1 kp 33 + + Safari key event behavior: + (Safari sets charCode and keyCode to something crazy for + special keys.) + key event charCode keyCode + DOWN ku,kd 63233 40 + DOWN kp 63233 63233 + ESC ku,kd 27 27 + ESC kp 27 27 + a ku,kd 97 65 + a kp 97 97 + shift+a ku,kd 65 65 + shift+a kp 65 65 + 1 ku,kd 49 49 + 1 kp 49 49 + shift+1 ku,kd 33 49 + shift+1 kp 33 33 + + */ + + /* look for special keys here */ + if (this.type() == 'keydown' || this.type() == 'keyup') { + k.code = this._event.keyCode; + k.string = (MochiKit.Signal._specialKeys[k.code] || + 'KEY_UNKNOWN'); + return k; + + /* look for characters here */ + } else if (this.type() == 'keypress') { + + /* + + Special key behavior: + + IE: does not fire keypress events for special keys + FF: sets charCode to 0, and sets the correct keyCode + Safari: sets keyCode and charCode to something stupid + + */ + + k.code = 0; + k.string = ''; + + if (typeof(this._event.charCode) != 'undefined' && + this._event.charCode !== 0 && + !MochiKit.Signal._specialMacKeys[this._event.charCode]) { + k.code = this._event.charCode; + k.string = String.fromCharCode(k.code); + } else if (this._event.keyCode && + typeof(this._event.charCode) == 'undefined') { // IE + k.code = this._event.keyCode; + k.string = String.fromCharCode(k.code); + } + + return k; + } + } + // throw new Error('This is not a key event'); + return undefined; + }, + + mouse: function () { + var m = {}; + var e = this._event; + + if (this.type() && ( + this.type().indexOf('mouse') === 0 || + this.type().indexOf('click') != -1 || + this.type() == 'contextmenu')) { + + m.client = new MochiKit.DOM.Coordinates(0, 0); + if (e.clientX || e.clientY) { + m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX; + m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY; + } + + m.page = new MochiKit.DOM.Coordinates(0, 0); + if (e.pageX || e.pageY) { + m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX; + m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY; + } else { + /* + + IE keeps the document offset in: + document.documentElement.clientTop || + document.body.clientTop + + and: + document.documentElement.clientLeft || + document.body.clientLeft + + see: + http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp + + The offset is (2,2) in standards mode and (0,0) in quirks + mode. + + */ + + var de = MochiKit.DOM._document.documentElement; + var b = MochiKit.DOM._document.body; + + m.page.x = e.clientX + + (de.scrollLeft || b.scrollLeft) - + (de.clientLeft || b.clientLeft); + + m.page.y = e.clientY + + (de.scrollTop || b.scrollTop) - + (de.clientTop || b.clientTop); + + } + if (this.type() != 'mousemove') { + m.button = {}; + m.button.left = false; + m.button.right = false; + m.button.middle = false; + + /* we could check e.button, but which is more consistent */ + if (e.which) { + m.button.left = (e.which == 1); + m.button.middle = (e.which == 2); + m.button.right = (e.which == 3); + + /* + + Mac browsers and right click: + + - Safari doesn't fire any click events on a right + click: + http://bugzilla.opendarwin.org/show_bug.cgi?id=6595 + + - Firefox fires the event, and sets ctrlKey = true + + - Opera fires the event, and sets metaKey = true + + oncontextmenu is fired on right clicks between + browsers and across platforms. + + */ + + } else { + m.button.left = !!(e.button & 1); + m.button.right = !!(e.button & 2); + m.button.middle = !!(e.button & 4); + } + } + return m; + } + // throw new Error('This is not a mouse event'); + return undefined; + }, + + stop: function () { + this.stopPropagation(); + this.preventDefault(); + }, + + stopPropagation: function () { + if (this._event.stopPropagation) { + this._event.stopPropagation(); + } else { + this._event.cancelBubble = true; + } + }, + + preventDefault: function () { + if (this._event.preventDefault) { + this._event.preventDefault(); + } else { + this._event.returnValue = false; + } + } + +}); + +/* Safari sets keyCode to these special values onkeypress. */ +MochiKit.Signal._specialMacKeys = { + 3: 'KEY_ENTER', + 63289: 'KEY_NUM_PAD_CLEAR', + 63276: 'KEY_PAGE_UP', + 63277: 'KEY_PAGE_DOWN', + 63275: 'KEY_END', + 63273: 'KEY_HOME', + 63234: 'KEY_ARROW_LEFT', + 63232: 'KEY_ARROW_UP', + 63235: 'KEY_ARROW_RIGHT', + 63233: 'KEY_ARROW_DOWN', + 63302: 'KEY_INSERT', + 63272: 'KEY_DELETE' +}; + +/* for KEY_F1 - KEY_F12 */ +for (i = 63236; i <= 63242; i++) { + MochiKit.Signal._specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1); // no F0 +} + +/* Standard keyboard key codes. */ +MochiKit.Signal._specialKeys = { + 8: 'KEY_BACKSPACE', + 9: 'KEY_TAB', + 12: 'KEY_NUM_PAD_CLEAR', // weird, for Safari and Mac FF only + 13: 'KEY_ENTER', + 16: 'KEY_SHIFT', + 17: 'KEY_CTRL', + 18: 'KEY_ALT', + 19: 'KEY_PAUSE', + 20: 'KEY_CAPS_LOCK', + 27: 'KEY_ESCAPE', + 32: 'KEY_SPACEBAR', + 33: 'KEY_PAGE_UP', + 34: 'KEY_PAGE_DOWN', + 35: 'KEY_END', + 36: 'KEY_HOME', + 37: 'KEY_ARROW_LEFT', + 38: 'KEY_ARROW_UP', + 39: 'KEY_ARROW_RIGHT', + 40: 'KEY_ARROW_DOWN', + 44: 'KEY_PRINT_SCREEN', + 45: 'KEY_INSERT', + 46: 'KEY_DELETE', + 59: 'KEY_SEMICOLON', // weird, for Safari and IE only + 91: 'KEY_WINDOWS_LEFT', + 92: 'KEY_WINDOWS_RIGHT', + 93: 'KEY_SELECT', + 106: 'KEY_NUM_PAD_ASTERISK', + 107: 'KEY_NUM_PAD_PLUS_SIGN', + 109: 'KEY_NUM_PAD_HYPHEN-MINUS', + 110: 'KEY_NUM_PAD_FULL_STOP', + 111: 'KEY_NUM_PAD_SOLIDUS', + 144: 'KEY_NUM_LOCK', + 145: 'KEY_SCROLL_LOCK', + 186: 'KEY_SEMICOLON', + 187: 'KEY_EQUALS_SIGN', + 188: 'KEY_COMMA', + 189: 'KEY_HYPHEN-MINUS', + 190: 'KEY_FULL_STOP', + 191: 'KEY_SOLIDUS', + 192: 'KEY_GRAVE_ACCENT', + 219: 'KEY_LEFT_SQUARE_BRACKET', + 220: 'KEY_REVERSE_SOLIDUS', + 221: 'KEY_RIGHT_SQUARE_BRACKET', + 222: 'KEY_APOSTROPHE' + // undefined: 'KEY_UNKNOWN' +}; + +/* for KEY_0 - KEY_9 */ +for (var i = 48; i <= 57; i++) { + MochiKit.Signal._specialKeys[i] = 'KEY_' + (i - 48); +} + +/* for KEY_A - KEY_Z */ +for (i = 65; i <= 90; i++) { + MochiKit.Signal._specialKeys[i] = 'KEY_' + String.fromCharCode(i); +} + +/* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */ +for (i = 96; i <= 105; i++) { + MochiKit.Signal._specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96); +} + +/* for KEY_F1 - KEY_F12 */ +for (i = 112; i <= 123; i++) { + MochiKit.Signal._specialKeys[i] = 'KEY_F' + (i - 112 + 1); // no F0 +} + +MochiKit.Base.update(MochiKit.Signal, { + + __repr__: function () { + return '[' + this.NAME + ' ' + this.VERSION + ']'; + }, + + toString: function () { + return this.__repr__(); + }, + + _unloadCache: function () { + var self = MochiKit.Signal; + var observers = self._observers; + + for (var i = 0; i < observers.length; i++) { + self._disconnect(observers[i]); + } + + delete self._observers; + + try { + window.onload = undefined; + } catch(e) { + // pass + } + + try { + window.onunload = undefined; + } catch(e) { + // pass + } + }, + + _listener: function (src, func, obj, isDOM) { + var E = MochiKit.Signal.Event; + if (!isDOM) { + return MochiKit.Base.bind(func, obj); + } + obj = obj || src; + if (typeof(func) == "string") { + return function (nativeEvent) { + obj[func].apply(obj, [new E(src, nativeEvent)]); + }; + } else { + return function (nativeEvent) { + func.apply(obj, [new E(src, nativeEvent)]); + }; + } + }, + + connect: function (src, sig, objOrFunc/* optional */, funcOrStr) { + src = MochiKit.DOM.getElement(src); + var self = MochiKit.Signal; + + if (typeof(sig) != 'string') { + throw new Error("'sig' must be a string"); + } + + var obj = null; + var func = null; + if (typeof(funcOrStr) != 'undefined') { + obj = objOrFunc; + func = funcOrStr; + if (typeof(funcOrStr) == 'string') { + if (typeof(objOrFunc[funcOrStr]) != "function") { + throw new Error("'funcOrStr' must be a function on 'objOrFunc'"); + } + } else if (typeof(funcOrStr) != 'function') { + throw new Error("'funcOrStr' must be a function or string"); + } + } else if (typeof(objOrFunc) != "function") { + throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given"); + } else { + func = objOrFunc; + } + if (typeof(obj) == 'undefined' || obj === null) { + obj = src; + } + + var isDOM = !!(src.addEventListener || src.attachEvent); + var listener = self._listener(src, func, obj, isDOM); + + if (src.addEventListener) { + src.addEventListener(sig.substr(2), listener, false); + } else if (src.attachEvent) { + src.attachEvent(sig, listener); // useCapture unsupported + } + + var ident = [src, sig, listener, isDOM, objOrFunc, funcOrStr]; + self._observers.push(ident); + + + return ident; + }, + + _disconnect: function (ident) { + // check isDOM + if (!ident[3]) { return; } + var src = ident[0]; + var sig = ident[1]; + var listener = ident[2]; + if (src.removeEventListener) { + src.removeEventListener(sig.substr(2), listener, false); + } else if (src.detachEvent) { + src.detachEvent(sig, listener); // useCapture unsupported + } else { + throw new Error("'src' must be a DOM element"); + } + }, + + disconnect: function (ident) { + var self = MochiKit.Signal; + var observers = self._observers; + var m = MochiKit.Base; + if (arguments.length > 1) { + // compatibility API + var src = MochiKit.DOM.getElement(arguments[0]); + var sig = arguments[1]; + var obj = arguments[2]; + var func = arguments[3]; + for (var i = observers.length - 1; i >= 0; i--) { + var o = observers[i]; + if (o[0] === src && o[1] === sig && o[4] === obj && o[5] === func) { + self._disconnect(o); + observers.splice(i, 1); + return true; + } + } + } else { + var idx = m.findIdentical(observers, ident); + if (idx >= 0) { + self._disconnect(ident); + observers.splice(idx, 1); + return true; + } + } + return false; + }, + + disconnectAll: function(src/* optional */, sig) { + src = MochiKit.DOM.getElement(src); + var m = MochiKit.Base; + var signals = m.flattenArguments(m.extend(null, arguments, 1)); + var self = MochiKit.Signal; + var disconnect = self._disconnect; + var observers = self._observers; + if (signals.length === 0) { + // disconnect all + for (var i = observers.length - 1; i >= 0; i--) { + var ident = observers[i]; + if (ident[0] === src) { + disconnect(ident); + observers.splice(i, 1); + } + } + } else { + var sigs = {}; + for (var i = 0; i < signals.length; i++) { + sigs[signals[i]] = true; + } + for (var i = observers.length - 1; i >= 0; i--) { + var ident = observers[i]; + if (ident[0] === src && ident[1] in sigs) { + disconnect(ident); + observers.splice(i, 1); + } + } + } + + }, + + signal: function (src, sig) { + var observers = MochiKit.Signal._observers; + src = MochiKit.DOM.getElement(src); + var args = MochiKit.Base.extend(null, arguments, 2); + var errors = []; + for (var i = 0; i < observers.length; i++) { + var ident = observers[i]; + if (ident[0] === src && ident[1] === sig) { + try { + ident[2].apply(src, args); + } catch (e) { + errors.push(e); + } + } + } + if (errors.length == 1) { + throw errors[0]; + } else if (errors.length > 1) { + var e = new Error("Multiple errors thrown in handling 'sig', see errors property"); + e.errors = errors; + throw e; + } + } + +}); + +MochiKit.Signal.EXPORT_OK = []; + +MochiKit.Signal.EXPORT = [ + 'connect', + 'disconnect', + 'signal', + 'disconnectAll' +]; + +MochiKit.Signal.__new__ = function (win) { + var m = MochiKit.Base; + this._document = document; + this._window = win; + + try { + this.connect(window, 'onunload', this._unloadCache); + } catch (e) { + // pass: might not be a browser + } + + this.EXPORT_TAGS = { + ':common': this.EXPORT, + ':all': m.concat(this.EXPORT, this.EXPORT_OK) + }; + + m.nameFunctions(this); +}; + +MochiKit.Signal.__new__(this); + +// +// XXX: Internet Explorer blows +// +if (!MochiKit.__compat__) { + connect = MochiKit.Signal.connect; + disconnect = MochiKit.Signal.disconnect; + disconnectAll = MochiKit.Signal.disconnectAll; + signal = MochiKit.Signal.signal; +} + +MochiKit.Base._exportSymbols(this, MochiKit.Signal); diff --git a/webtools/new-graph/js/mochikit/Test.js b/webtools/new-graph/js/mochikit/Test.js new file mode 100644 index 00000000000..8517e7e571a --- /dev/null +++ b/webtools/new-graph/js/mochikit/Test.js @@ -0,0 +1,181 @@ +/*** + +MochiKit.Test 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.Test'); + dojo.require('MochiKit.Base'); +} + +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Base", []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.Test depends on MochiKit.Base!"; +} + +if (typeof(MochiKit.Test) == 'undefined') { + MochiKit.Test = {}; +} + +MochiKit.Test.NAME = "MochiKit.Test"; +MochiKit.Test.VERSION = "1.3.1"; +MochiKit.Test.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; + +MochiKit.Test.toString = function () { + return this.__repr__(); +}; + + +MochiKit.Test.EXPORT = ["runTests"]; +MochiKit.Test.EXPORT_OK = []; + +MochiKit.Test.runTests = function (obj) { + if (typeof(obj) == "string") { + obj = JSAN.use(obj); + } + var suite = new MochiKit.Test.Suite(); + suite.run(obj); +}; + +MochiKit.Test.Suite = function () { + this.testIndex = 0; + MochiKit.Base.bindMethods(this); +}; + +MochiKit.Test.Suite.prototype = { + run: function (obj) { + try { + obj(this); + } catch (e) { + this.traceback(e); + } + }, + traceback: function (e) { + var items = MochiKit.Iter.sorted(MochiKit.Base.items(e)); + print("not ok " + this.testIndex + " - Error thrown"); + for (var i = 0; i < items.length; i++) { + var kv = items[i]; + if (kv[0] == "stack") { + kv[1] = kv[1].split(/\n/)[0]; + } + this.print("# " + kv.join(": ")); + } + }, + print: function (s) { + print(s); + }, + is: function (got, expected, /* optional */message) { + var res = 1; + var msg = null; + try { + res = MochiKit.Base.compare(got, expected); + } catch (e) { + msg = "Can not compare " + typeof(got) + ":" + typeof(expected); + } + if (res) { + msg = "Expected value did not compare equal"; + } + if (!res) { + return this.testResult(true, message); + } + return this.testResult(false, message, + [[msg], ["got:", got], ["expected:", expected]]); + }, + + testResult: function (pass, msg, failures) { + this.testIndex += 1; + if (pass) { + this.print("ok " + this.testIndex + " - " + msg); + return; + } + this.print("not ok " + this.testIndex + " - " + msg); + if (failures) { + for (var i = 0; i < failures.length; i++) { + this.print("# " + failures[i].join(" ")); + } + } + }, + + isDeeply: function (got, expected, /* optional */message) { + var m = MochiKit.Base; + var res = 1; + try { + res = m.compare(got, expected); + } catch (e) { + // pass + } + if (res === 0) { + return this.ok(true, message); + } + var gk = m.keys(got); + var ek = m.keys(expected); + gk.sort(); + ek.sort(); + if (m.compare(gk, ek)) { + // differing keys + var cmp = {}; + var i; + for (i = 0; i < gk.length; i++) { + cmp[gk[i]] = "got"; + } + for (i = 0; i < ek.length; i++) { + if (ek[i] in cmp) { + delete cmp[ek[i]]; + } else { + cmp[ek[i]] = "expected"; + } + } + var diffkeys = m.keys(cmp); + diffkeys.sort(); + var gotkeys = []; + var expkeys = []; + while (diffkeys.length) { + var k = diffkeys.shift(); + if (k in Object.prototype) { + continue; + } + (cmp[k] == "got" ? gotkeys : expkeys).push(k); + } + + + } + + return this.testResult((!res), msg, + (msg ? [["got:", got], ["expected:", expected]] : undefined) + ); + }, + + ok: function (res, message) { + return this.testResult(res, message); + } +}; + +MochiKit.Test.__new__ = function () { + var m = MochiKit.Base; + + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": m.concat(this.EXPORT, this.EXPORT_OK) + }; + + m.nameFunctions(this); + +}; + +MochiKit.Test.__new__(); + +MochiKit.Base._exportSymbols(this, MochiKit.Test); diff --git a/webtools/new-graph/js/mochikit/Visual.js b/webtools/new-graph/js/mochikit/Visual.js new file mode 100644 index 00000000000..02cee54fabc --- /dev/null +++ b/webtools/new-graph/js/mochikit/Visual.js @@ -0,0 +1,402 @@ +/*** + +MochiKit.Visual 1.3.1 + +See for documentation, downloads, license, etc. + +(c) 2005 Bob Ippolito and others. All rights Reserved. + +***/ + +if (typeof(dojo) != 'undefined') { + dojo.provide('MochiKit.Visual'); + dojo.require('MochiKit.Base'); + dojo.require('MochiKit.DOM'); + dojo.require('MochiKit.Color'); +} + +if (typeof(JSAN) != 'undefined') { + JSAN.use("MochiKit.Base", []); + JSAN.use("MochiKit.DOM", []); + JSAN.use("MochiKit.Color", []); +} + +try { + if (typeof(MochiKit.Base) == 'undefined' || + typeof(MochiKit.DOM) == 'undefined' || + typeof(MochiKit.Color) == 'undefined') { + throw ""; + } +} catch (e) { + throw "MochiKit.Visual depends on MochiKit.Base, MochiKit.DOM and MochiKit.Color!"; +} + +if (typeof(MochiKit.Visual) == "undefined") { + MochiKit.Visual = {}; +} + +MochiKit.Visual.NAME = "MochiKit.Visual"; +MochiKit.Visual.VERSION = "1.3.1"; + +MochiKit.Visual.__repr__ = function () { + return "[" + this.NAME + " " + this.VERSION + "]"; +}; + +MochiKit.Visual.toString = function () { + return this.__repr__(); +}; + + +MochiKit.Visual._RoundCorners = function (e, options) { + e = MochiKit.DOM.getElement(e); + this._setOptions(options); + if (this.options.__unstable__wrapElement) { + e = this._doWrap(e); + } + + var color = this.options.color; + var C = MochiKit.Color.Color; + if (this.options.color == "fromElement") { + color = C.fromBackground(e); + } else if (!(color instanceof C)) { + color = C.fromString(color); + } + this.isTransparent = (color.asRGB().a <= 0); + + var bgColor = this.options.bgColor; + if (this.options.bgColor == "fromParent") { + bgColor = C.fromBackground(e.offsetParent); + } else if (!(bgColor instanceof C)) { + bgColor = C.fromString(bgColor); + } + + this._roundCornersImpl(e, color, bgColor); +}; + +MochiKit.Visual._RoundCorners.prototype = { + _doWrap: function (e) { + var parent = e.parentNode; + var doc = MochiKit.DOM.currentDocument(); + if (typeof(doc.defaultView) == "undefined" + || doc.defaultView === null) { + return e; + } + var style = doc.defaultView.getComputedStyle(e, null); + if (typeof(style) == "undefined" || style === null) { + return e; + } + var wrapper = MochiKit.DOM.DIV({"style": { + display: "block", + // convert padding to margin + marginTop: style.getPropertyValue("padding-top"), + marginRight: style.getPropertyValue("padding-right"), + marginBottom: style.getPropertyValue("padding-bottom"), + marginLeft: style.getPropertyValue("padding-left"), + // remove padding so the rounding looks right + padding: "0px" + /* + paddingRight: "0px", + paddingLeft: "0px" + */ + }}); + wrapper.innerHTML = e.innerHTML; + e.innerHTML = ""; + e.appendChild(wrapper); + return e; + }, + + _roundCornersImpl: function (e, color, bgColor) { + if (this.options.border) { + this._renderBorder(e, bgColor); + } + if (this._isTopRounded()) { + this._roundTopCorners(e, color, bgColor); + } + if (this._isBottomRounded()) { + this._roundBottomCorners(e, color, bgColor); + } + }, + + _renderBorder: function (el, bgColor) { + var borderValue = "1px solid " + this._borderColor(bgColor); + var borderL = "border-left: " + borderValue; + var borderR = "border-right: " + borderValue; + var style = "style='" + borderL + ";" + borderR + "'"; + el.innerHTML = "
" + el.innerHTML + "
"; + }, + + _roundTopCorners: function (el, color, bgColor) { + var corner = this._createCorner(bgColor); + for (var i = 0; i < this.options.numSlices; i++) { + corner.appendChild( + this._createCornerSlice(color, bgColor, i, "top") + ); + } + el.style.paddingTop = 0; + el.insertBefore(corner, el.firstChild); + }, + + _roundBottomCorners: function (el, color, bgColor) { + var corner = this._createCorner(bgColor); + for (var i = (this.options.numSlices - 1); i >= 0; i--) { + corner.appendChild( + this._createCornerSlice(color, bgColor, i, "bottom") + ); + } + el.style.paddingBottom = 0; + el.appendChild(corner); + }, + + _createCorner: function (bgColor) { + var dom = MochiKit.DOM; + return dom.DIV({style: {backgroundColor: bgColor.toString()}}); + }, + + _createCornerSlice: function (color, bgColor, n, position) { + var slice = MochiKit.DOM.SPAN(); + + var inStyle = slice.style; + inStyle.backgroundColor = color.toString(); + inStyle.display = "block"; + inStyle.height = "1px"; + inStyle.overflow = "hidden"; + inStyle.fontSize = "1px"; + + var borderColor = this._borderColor(color, bgColor); + if (this.options.border && n === 0) { + inStyle.borderTopStyle = "solid"; + inStyle.borderTopWidth = "1px"; + inStyle.borderLeftWidth = "0px"; + inStyle.borderRightWidth = "0px"; + inStyle.borderBottomWidth = "0px"; + // assumes css compliant box model + inStyle.height = "0px"; + inStyle.borderColor = borderColor.toString(); + } else if (borderColor) { + inStyle.borderColor = borderColor.toString(); + inStyle.borderStyle = "solid"; + inStyle.borderWidth = "0px 1px"; + } + + if (!this.options.compact && (n == (this.options.numSlices - 1))) { + inStyle.height = "2px"; + } + + this._setMargin(slice, n, position); + this._setBorder(slice, n, position); + + return slice; + }, + + _setOptions: function (options) { + this.options = { + corners: "all", + color: "fromElement", + bgColor: "fromParent", + blend: true, + border: false, + compact: false, + __unstable__wrapElement: false + }; + MochiKit.Base.update(this.options, options); + + this.options.numSlices = (this.options.compact ? 2 : 4); + }, + + _whichSideTop: function () { + var corners = this.options.corners; + if (this._hasString(corners, "all", "top")) { + return ""; + } + + var has_tl = (corners.indexOf("tl") != -1); + var has_tr = (corners.indexOf("tr") != -1); + if (has_tl && has_tr) { + return ""; + } + if (has_tl) { + return "left"; + } + if (has_tr) { + return "right"; + } + return ""; + }, + + _whichSideBottom: function () { + var corners = this.options.corners; + if (this._hasString(corners, "all", "bottom")) { + return ""; + } + + var has_bl = (corners.indexOf('bl') != -1); + var has_br = (corners.indexOf('br') != -1); + if (has_bl && has_br) { + return ""; + } + if (has_bl) { + return "left"; + } + if (has_br) { + return "right"; + } + return ""; + }, + + _borderColor: function (color, bgColor) { + if (color == "transparent") { + return bgColor; + } else if (this.options.border) { + return this.options.border; + } else if (this.options.blend) { + return bgColor.blendedColor(color); + } + return ""; + }, + + + _setMargin: function (el, n, corners) { + var marginSize = this._marginSize(n) + "px"; + var whichSide = ( + corners == "top" ? this._whichSideTop() : this._whichSideBottom() + ); + var style = el.style; + + if (whichSide == "left") { + style.marginLeft = marginSize; + style.marginRight = "0px"; + } else if (whichSide == "right") { + style.marginRight = marginSize; + style.marginLeft = "0px"; + } else { + style.marginLeft = marginSize; + style.marginRight = marginSize; + } + }, + + _setBorder: function (el, n, corners) { + var borderSize = this._borderSize(n) + "px"; + var whichSide = ( + corners == "top" ? this._whichSideTop() : this._whichSideBottom() + ); + + var style = el.style; + if (whichSide == "left") { + style.borderLeftWidth = borderSize; + style.borderRightWidth = "0px"; + } else if (whichSide == "right") { + style.borderRightWidth = borderSize; + style.borderLeftWidth = "0px"; + } else { + style.borderLeftWidth = borderSize; + style.borderRightWidth = borderSize; + } + }, + + _marginSize: function (n) { + if (this.isTransparent) { + return 0; + } + + var o = this.options; + if (o.compact && o.blend) { + var smBlendedMarginSizes = [1, 0]; + return smBlendedMarginSizes[n]; + } else if (o.compact) { + var compactMarginSizes = [2, 1]; + return compactMarginSizes[n]; + } else if (o.blend) { + var blendedMarginSizes = [3, 2, 1, 0]; + return blendedMarginSizes[n]; + } else { + var marginSizes = [5, 3, 2, 1]; + return marginSizes[n]; + } + }, + + _borderSize: function (n) { + var o = this.options; + var borderSizes; + if (o.compact && (o.blend || this.isTransparent)) { + return 1; + } else if (o.compact) { + borderSizes = [1, 0]; + } else if (o.blend) { + borderSizes = [2, 1, 1, 1]; + } else if (o.border) { + borderSizes = [0, 2, 0, 0]; + } else if (this.isTransparent) { + borderSizes = [5, 3, 2, 1]; + } else { + return 0; + } + return borderSizes[n]; + }, + + _hasString: function (str) { + for (var i = 1; i< arguments.length; i++) { + if (str.indexOf(arguments[i]) != -1) { + return true; + } + } + return false; + }, + + _isTopRounded: function () { + return this._hasString(this.options.corners, + "all", "top", "tl", "tr" + ); + }, + + _isBottomRounded: function () { + return this._hasString(this.options.corners, + "all", "bottom", "bl", "br" + ); + }, + + _hasSingleTextChild: function (el) { + return (el.childNodes.length == 1 && el.childNodes[0].nodeType == 3); + } +}; + +MochiKit.Visual.roundElement = function (e, options) { + new MochiKit.Visual._RoundCorners(e, options); +}; + +MochiKit.Visual.roundClass = function (tagName, className, options) { + var elements = MochiKit.DOM.getElementsByTagAndClassName( + tagName, className + ); + for (var i = 0; i < elements.length; i++) { + MochiKit.Visual.roundElement(elements[i], options); + } +}; + +// Compatibility with MochiKit 1.0 +MochiKit.Visual.Color = MochiKit.Color.Color; +MochiKit.Visual.getElementsComputedStyle = MochiKit.DOM.computedStyle; + +/* end of Rico adaptation */ + +MochiKit.Visual.__new__ = function () { + var m = MochiKit.Base; + + m.nameFunctions(this); + + this.EXPORT_TAGS = { + ":common": this.EXPORT, + ":all": m.concat(this.EXPORT, this.EXPORT_OK) + }; + +}; + +MochiKit.Visual.EXPORT = [ + "roundElement", + "roundClass" +]; + +MochiKit.Visual.EXPORT_OK = []; + +MochiKit.Visual.__new__(); + +MochiKit.Base._exportSymbols(this, MochiKit.Visual); diff --git a/webtools/new-graph/js/mochikit/__package__.js b/webtools/new-graph/js/mochikit/__package__.js new file mode 100644 index 00000000000..18eb81daba9 --- /dev/null +++ b/webtools/new-graph/js/mochikit/__package__.js @@ -0,0 +1,17 @@ +dojo.hostenv.conditionalLoadModule({ + "common": [ + "MochiKit.Base", + "MochiKit.Iter", + "MochiKit.Logging", + "MochiKit.DateTime", + "MochiKit.Format", + "MochiKit.Async", + "MochiKit.Color" + ], + "browser": [ + "MochiKit.DOM", + "MochiKit.LoggingPane", + "MochiKit.Visual" + ] +}); +dojo.hostenv.moduleLoaded("MochiKit.*"); diff --git a/webtools/new-graph/js/yui/animation.js b/webtools/new-graph/js/yui/animation.js new file mode 100644 index 00000000000..fc41fce842b --- /dev/null +++ b/webtools/new-graph/js/yui/animation.js @@ -0,0 +1,7 @@ +/* +Copyright (c) 2006, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 0.10.0 +*/ +YAHOO.util.Anim=function(el,attributes,duration,method){if(el){this.init(el,attributes,duration,method);}};YAHOO.util.Anim.prototype={doMethod:function(attribute,start,end){return this.method(this.currentFrame,start,end-start,this.totalFrames);},setAttribute:function(attribute,val,unit){YAHOO.util.Dom.setStyle(this.getEl(),attribute,val+unit);},getAttribute:function(attribute){return parseFloat(YAHOO.util.Dom.getStyle(this.getEl(),attribute));},defaultUnit:'px',defaultUnits:{opacity:' '},init:function(el,attributes,duration,method){var isAnimated=false;var startTime=null;var endTime=null;var actualFrames=0;var defaultValues={};el=YAHOO.util.Dom.get(el);this.attributes=attributes||{};this.duration=duration||1;this.method=method||YAHOO.util.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=YAHOO.util.AnimMgr.fps;this.getEl=function(){return el;};this.setDefault=function(attribute,val){if(val.constructor!=Array&&(val=='auto'||isNaN(val))){switch(attribute){case'width':val=el.clientWidth||el.offsetWidth;break;case'height':val=el.clientHeight||el.offsetHeight;break;case'left':if(YAHOO.util.Dom.getStyle(el,'position')=='absolute'){val=el.offsetLeft;}else{val=0;}break;case'top':if(YAHOO.util.Dom.getStyle(el,'position')=='absolute'){val=el.offsetTop;}else{val=0;}break;default:val=0;}}defaultValues[attribute]=val;};this.getDefault=function(attribute){return defaultValues[attribute];};this.isAnimated=function(){return isAnimated;};this.getStartTime=function(){return startTime;};this.animate=function(){if(this.isAnimated()){return false;}this.onStart.fire();this._onStart.fire();this.totalFrames=(this.useSeconds)?Math.ceil(YAHOO.util.AnimMgr.fps*this.duration):this.duration;YAHOO.util.AnimMgr.registerElement(this);var attributes=this.attributes;var el=this.getEl();var val;for(var attribute in attributes){val=this.getAttribute(attribute);this.setDefault(attribute,val);}isAnimated=true;actualFrames=0;startTime=new Date();};this.stop=function(){if(!this.isAnimated()){return false;}this.currentFrame=0;endTime=new Date();var data={time:endTime,duration:endTime-startTime,frames:actualFrames,fps:actualFrames/this.duration};isAnimated=false;actualFrames=0;this.onComplete.fire(data);};var onTween=function(){var start;var end=null;var val;var unit;var attributes=this['attributes'];for(var attribute in attributes){unit=attributes[attribute]['unit']||this.defaultUnits[attribute]||this.defaultUnit;if(typeof attributes[attribute]['from']!='undefined'){start=attributes[attribute]['from'];}else{start=this.getDefault(attribute);}if(typeof attributes[attribute]['to']!='undefined'){end=attributes[attribute]['to'];}else if(typeof attributes[attribute]['by']!='undefined'){if(start.constructor==Array){end=[];for(var i=0,len=start.length;i0&&isFinite(tweak)){if(tween.currentFrame+tweak>=frames){tweak=frames-(frame+1);}tween.currentFrame+=tweak;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(points,t){var n=points.length;var tmp=[];for(var i=0;i0&&control[0].constructor!=Array){control=[control];}if(YAHOO.util.Dom.getStyle(this.getEl(),'position')=='static'){YAHOO.util.Dom.setStyle(this.getEl(),'position','relative');}if(typeof attributes['points']['from']!='undefined'){YAHOO.util.Dom.setXY(this.getEl(),attributes['points']['from']);start=this.getAttribute('points');}else if((start[0]===0||start[1]===0)){YAHOO.util.Dom.setXY(this.getEl(),YAHOO.util.Dom.getXY(this.getEl()));start=this.getAttribute('points');}var i,len;if(typeof attributes['points']['to']!='undefined'){end=translateValues(attributes['points']['to'],this);for(i=0,len=control.length;i0){translatedPoints=translatedPoints.concat(control);}translatedPoints[translatedPoints.length]=end;}};this._onStart.subscribe(onStart);};YAHOO.util.Scroll=function(el,attributes,duration,method){if(el){YAHOO.util.Anim.call(this,el,attributes,duration,method);}};YAHOO.util.Scroll.prototype=new YAHOO.util.Anim();YAHOO.util.Scroll.prototype.defaultUnits.scroll=' ';YAHOO.util.Scroll.prototype.doMethod=function(attribute,start,end){var val=null;if(attribute=='scroll'){val=[this.method(this.currentFrame,start[0],end[0]-start[0],this.totalFrames),this.method(this.currentFrame,start[1],end[1]-start[1],this.totalFrames)];}else{val=this.method(this.currentFrame,start,end-start,this.totalFrames);}return val;};YAHOO.util.Scroll.prototype.getAttribute=function(attribute){var val=null;var el=this.getEl();if(attribute=='scroll'){val=[el.scrollLeft,el.scrollTop];}else{val=parseFloat(YAHOO.util.Dom.getStyle(el,attribute));}return val;};YAHOO.util.Scroll.prototype.setAttribute=function(attribute,val,unit){var el=this.getEl();if(attribute=='scroll'){el.scrollLeft=val[0];el.scrollTop=val[1];}else{YAHOO.util.Dom.setStyle(el,attribute,val+unit);}}; diff --git a/webtools/new-graph/js/yui/assets/alrt16_1.gif b/webtools/new-graph/js/yui/assets/alrt16_1.gif new file mode 100644 index 00000000000..443d39bbfcd Binary files /dev/null and b/webtools/new-graph/js/yui/assets/alrt16_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/blck16_1.gif b/webtools/new-graph/js/yui/assets/blck16_1.gif new file mode 100644 index 00000000000..56689611db2 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/blck16_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/calendar.css b/webtools/new-graph/js/yui/assets/calendar.css new file mode 100644 index 00000000000..464582faac4 --- /dev/null +++ b/webtools/new-graph/js/yui/assets/calendar.css @@ -0,0 +1,163 @@ +/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ +/* Container Styles */ + +.calcontainer {*height:1%;} /* IE */ +.calcontainer:after {content:'.';clear:both;display:block;visibility:hidden;height:0;} /* others */ + +.calbordered { + float:left; + padding:5px; + background-color:#F7F9FB; + border:1px solid #7B9EBD; +} + +.calbordered .title { + font:73% Arial,Helvetica,sans-serif; + color:#000; + font-weight:bold; + margin-bottom:5px; + height:auto; + width:304px; + position:relative; +} + +.title .close-icon { + position:absolute; + right:0; + top:0; + border:none; +} + +.cal2up { + float:left; +} + +.calnavleft { + position:absolute; + top:0; + bottom:0; + height:12px; + left:2px; +} + +.calnavright { + position:absolute; + top:0; + bottom:0; + height:12px; + right:2px; +} + +/* Calendar element styles */ + +.calendar { + font:73% Arial,Helvetica,sans-serif; + text-align:center; + border-spacing:0; +} + +td.calcell { + width:1.5em; + height:1em; + border:1px solid #E0E0E0; + background-color:#FFF; +} + +.calendar.wait td.calcell { + color:#999; + background-color:#CCC; +} + +.calendar.wait td.calcell a { + color:#999; + font-style:italic; +} + +td.calcell a { + color:#003DB8; + text-decoration:none; +} + +td.calcell.today { + border:1px solid #000; +} + +td.calcell.oom { + cursor:default; + color:#999; + background-color:#EEE; + border:1px solid #E0E0E0; +} + +td.calcell.selected { + color:#003DB8; + background-color:#FFF19F; + border:1px solid #FF9900; +} + +td.calcell.calcellhover { + cursor:pointer; + color:#FFF; + background-color:#FF9900; + border:1px solid #FF9900; +} + +/* Added to perform some correction for Opera 8.5 + hover redraw bug */ +table:hover { + background-color:#FFF; +} + +td.calcell.calcellhover a { + color:#FFF; +} + +td.calcell.restricted { + text-decoration:line-through; +} + +td.calcell.previous { + color:#CCC; +} + +td.calcell.highlight1 { background-color:#CCFF99; } +td.calcell.highlight2 { background-color:#99CCFF; } +td.calcell.highlight3 { background-color:#FFCCCC; } +td.calcell.highlight4 { background-color:#CCFF99; } + + +.calhead { + border:1px solid #E0E0E0; + vertical-align:middle; + background-color:#FFF; +} + +.calheader { + position:relative; + width:100%; +} + +.calheader img { + border:none; +} + +.calweekdaycell { + color:#666; + font-weight:normal; +} + +.calfoot { + background-color:#EEE; +} + +.calrowhead, .calrowfoot { + color:#666; + font-size:9px; + font-style:italic; + font-weight:normal; + width:15px; +} + +.calrowhead { + border-right-width:2px; +} diff --git a/webtools/new-graph/js/yui/assets/callt.gif b/webtools/new-graph/js/yui/assets/callt.gif new file mode 100644 index 00000000000..a6cc8da5b22 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/callt.gif differ diff --git a/webtools/new-graph/js/yui/assets/calrt.gif b/webtools/new-graph/js/yui/assets/calrt.gif new file mode 100644 index 00000000000..ee137b2ff76 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/calrt.gif differ diff --git a/webtools/new-graph/js/yui/assets/calx.gif b/webtools/new-graph/js/yui/assets/calx.gif new file mode 100644 index 00000000000..27e7bc36e45 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/calx.gif differ diff --git a/webtools/new-graph/js/yui/assets/close12_1.gif b/webtools/new-graph/js/yui/assets/close12_1.gif new file mode 100644 index 00000000000..e2f67d72efc Binary files /dev/null and b/webtools/new-graph/js/yui/assets/close12_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/container.css b/webtools/new-graph/js/yui/assets/container.css new file mode 100644 index 00000000000..8f1b539330e --- /dev/null +++ b/webtools/new-graph/js/yui/assets/container.css @@ -0,0 +1,206 @@ +.overlay { + position:absolute; + display:block; +} + +.tt { + visibility:hidden; + position:absolute; + color:#333; + background-color:#FDFFB4; + font-family:arial,helvetica,verdana,sans-serif; + padding:2px; + border:1px solid #FCC90D; + font:100% sans-serif; + width:auto; +} + +* html body.masked select { + visibility:hidden; +} + +* html div.panel-container select { + visibility:inherit; +} + +* html div.drag select { + visibility:hidden; +} + +* html div.hide-select select { + visibility:hidden; +} + +.mask { + z-index:0; + display:none; + position:absolute; + top:0; + left:0; + background-color:#CCC; + -moz-opacity: 0.5; + opacity:.50; + filter: alpha(opacity=50); + } +.mask[id]{ /* IE6 and below Can't See This */ + position:fixed; +} + +.hide-scrollbars * { + overflow:hidden; +} + +.hide-scrollbars textarea, .hide-scrollbars select { + overflow:hidden; + display:none; +} + +.show-scrollbars textarea, .show-scrollbars select { + overflow:visible; +} + +.panel-container { + position:absolute; + background-color:transparent; + z-index:6; + visibility:hidden; + overflow:visible; + width:auto; +} + +.panel-container.matte { + padding:3px; + background-color:#FFF; +} + +.panel-container.matte .underlay { + display:none; +} + +.panel-container.shadow { + padding:0px; + background-color:transparent; +} + +.panel-container.shadow .underlay { + visibility:inherit; + position:absolute; + background-color:#CCC; + top:3px;left:3px; + z-index:0; + width:100%; + height:100%; + -moz-opacity: 0.7; + opacity:.70; + filter:alpha(opacity=70); +} + +.panel { + visibility:hidden; + border-collapse:separate; + position:relative; + left:0px;top:0px; + font:1em Arial; + background-color:#FFF; + border:1px solid #000; + z-index:1; + overflow:auto; +} + +.panel .hd { + background-color:#3d77cb; + color:#FFF; + font-size:1em; + height:1em; + border:1px solid #FFF; + border-bottom:1px solid #000; + font-weight:bold; + overflow:hidden; + padding:4px; +} + +.panel .bd { + overflow:hidden; + padding:4px; +} + +.panel .bd p { + margin:0 0 1em; +} + +.panel .close { + position:absolute; + top:5px; + right:4px; + z-index:6; + height:12px; + width:12px; + margin:0px; + padding:0px; + background-repeat:no-repeat; + cursor:pointer; + visibility:inherit; +} + +.panel .close.nonsecure { + background-image:url(http://us.i1.yimg.com/us.yimg.com/i/nt/ic/ut/alt3/close12_1.gif); +} + +.panel .close.secure { + background-image:url(https://a248.e.akamai.net/sec.yimg.com/i/nt/ic/ut/alt3/close12_1.gif); +} + +.panel .ft { + padding:4px; + overflow:hidden; +} + +.simple-dialog .bd .icon { + background-repeat:no-repeat; + width:16px; + height:16px; + margin-right:10px; + float:left; +} + +.dialog .ft, .simple-dialog .ft { + padding-bottom:5px; + padding-right:5px; + text-align:right; +} + +.dialog form, .simple-dialog form { + margin:0; +} + +.button-group button { + font:100 76% verdana; + text-decoration:none; + background-color: #E4E4E4; + color: #333; + cursor: hand; + vertical-align: middle; + border: 2px solid #797979; + border-top-color:#FFF; + border-left-color:#FFF; + margin:2px; + padding:2px; +} + +.button-group button.default { + font-weight:bold; +} + +.button-group button:hover, .button-group button.hover { + border:2px solid #90A029; + background-color:#EBF09E; + border-top-color:#FFF; + border-left-color:#FFF; +} + +.button-group button:active { + border:2px solid #E4E4E4; + background-color:#BBB; + border-top-color:#333; + border-left-color:#333; +} diff --git a/webtools/new-graph/js/yui/assets/hlp16_1.gif b/webtools/new-graph/js/yui/assets/hlp16_1.gif new file mode 100644 index 00000000000..4645c8fdfa6 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/hlp16_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/info16_1.gif b/webtools/new-graph/js/yui/assets/info16_1.gif new file mode 100644 index 00000000000..22f697a9917 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/info16_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/lm.gif b/webtools/new-graph/js/yui/assets/lm.gif new file mode 100644 index 00000000000..e7d0a3ce92e Binary files /dev/null and b/webtools/new-graph/js/yui/assets/lm.gif differ diff --git a/webtools/new-graph/js/yui/assets/lmh.gif b/webtools/new-graph/js/yui/assets/lmh.gif new file mode 100644 index 00000000000..3ff6302723f Binary files /dev/null and b/webtools/new-graph/js/yui/assets/lmh.gif differ diff --git a/webtools/new-graph/js/yui/assets/ln.gif b/webtools/new-graph/js/yui/assets/ln.gif new file mode 100644 index 00000000000..b7b3e55cd04 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/ln.gif differ diff --git a/webtools/new-graph/js/yui/assets/loading.gif b/webtools/new-graph/js/yui/assets/loading.gif new file mode 100644 index 00000000000..0bbf3bc0c0e Binary files /dev/null and b/webtools/new-graph/js/yui/assets/loading.gif differ diff --git a/webtools/new-graph/js/yui/assets/lp.gif b/webtools/new-graph/js/yui/assets/lp.gif new file mode 100644 index 00000000000..b87f0031545 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/lp.gif differ diff --git a/webtools/new-graph/js/yui/assets/lph.gif b/webtools/new-graph/js/yui/assets/lph.gif new file mode 100644 index 00000000000..e3478d8e37d Binary files /dev/null and b/webtools/new-graph/js/yui/assets/lph.gif differ diff --git a/webtools/new-graph/js/yui/assets/menu.css b/webtools/new-graph/js/yui/assets/menu.css new file mode 100644 index 00000000000..faba48b16cf --- /dev/null +++ b/webtools/new-graph/js/yui/assets/menu.css @@ -0,0 +1,264 @@ +/* +Copyright (c) 2006, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +*/ + + +/* Menu styles */ + +div.yuimenu { + + z-index:1; + visibility:hidden; + background-color:#f6f7ee; + border:solid 1px #c4c4be; + padding:1px; + +} + + +/* MenuBar Styles */ + +div.yuimenubar { + + background-color:#f6f7ee; + +} + +/* + Application of "zoom:1" triggers "haslayout" in IE so that the module's + body clears its floated elements +*/ +div.yuimenubar div.bd { + + zoom:1; + +} + +/* + Clear the module body for other browsers +*/ +div.yuimenubar div.bd:after { + + content:'.'; + display:block; + clear:both; + visibility:hidden; + height:0; + +} + + +/* Matches the group title (H6) inside a Menu or MenuBar instance */ + +div.yuimenu h6, +div.yuimenubar h6 { + + font-size:100%; + font-weight:normal; + margin:0; + border:solid 1px #c4c4be; + color:#b9b9b9; + +} + +div.yuimenubar h6 { + + float:left; + display:inline; /* Prevent margin doubling in IE */ + padding:4px 12px; + border-width:0 1px 0 0; + +} + +div.yuimenu h6 { + + float:none; + display:block; + border-width:1px 0 0 0; + padding:5px 10px 0 10px; + +} + + +/* Matches the UL inside a Menu or MenuBar instance */ + +div.yuimenubar ul { + + list-style-type:none; + margin:0; + padding:0; + overflow:hidden; + +} + +div.yuimenu ul { + + list-style-type:none; + border:solid 1px #c4c4be; + border-width:1px 0 0 0; + margin:0; + padding:10px 0; + +} + + +div.yuimenu ul.first, +div.yuimenu ul.hastitle, +div.yuimenu h6.first { + + border-width:0; + +} + + +/* MenuItem and MenuBarItem styles */ + +div.yuimenu li, +div.yuimenubar li { + + font-size:85%; + cursor:pointer; + cursor:hand; + white-space:nowrap; + text-align:left; + +} + +div.yuimenu li.yuimenuitem { + + padding:2px 24px; + +} + +div.yuimenu li li, +div.yuimenubar li li { + + font-size:100%; + +} + + +/* Matches the help text for a MenuItem instance */ + +div.yuimenu li em { + + font-style:normal; + margin:0 0 0 40px; + +} + +div.yuimenu li a em { + + margin:0; + +} + +div.yuimenu li a, +div.yuimenubar li a { + + /* + "zoom:1" triggers "haslayout" in IE to ensure that the mouseover and + mouseout events bubble to the parent LI in IE. + */ + zoom:1; + color:#000; + text-decoration:none; + +} + + +/* Matches the sub menu indicator for a MenuItem instance */ + +div.yuimenu li img { + + margin:0 -16px 0 10px; + border:0; + +} + +div.yuimenu li.hassubmenu, +div.yuimenu li.hashelptext { + + text-align:right; + +} + +div.yuimenu li.hassubmenu a.hassubmenu, +div.yuimenu li.hashelptext a.hashelptext { + + float:left; + display:inline; /* Prevent margin doubling in IE */ + text-align:left; + +} + + +/* Matches focused and selected MenuItem instances */ + +div.yuimenu li.selected, +div.yuimenubar li.selected { + + background-color:#8c8ad0; + +} + +div.yuimenu li.selected a.selected, +div.yuimenubar li.selected a.selected { + + text-decoration:underline; + +} + +div.yuimenu li.selected a.selected, +div.yuimenu li.selected em.selected, +div.yuimenubar li.selected a.selected { + + color:#fff; + +} + + +/* Matches disabled MenuItem instances */ + +div.yuimenu li.disabled, +div.yuimenubar li.disabled { + + cursor:default; + +} + +div.yuimenu li.disabled a.disabled, +div.yuimenu li.disabled em.disabled, +div.yuimenubar li.disabled a.disabled { + + color:#b9b9b9; + cursor:default; + +} + +div.yuimenubar li.yuimenubaritem { + + float:left; + display:inline; /* Prevent margin doubling in IE */ + border-width:0 0 0 1px; + border-style:solid; + border-color:#c4c4be; + padding:4px 24px; + margin:0; + +} + +div.yuimenubar li.yuimenubaritem.first { + + border-width:0; + +} + +div.yuimenubar li.yuimenubaritem img { + + margin:0 0 0 10px; + vertical-align:middle; + +} \ No newline at end of file diff --git a/webtools/new-graph/js/yui/assets/menuarodwn9_clk_1.gif b/webtools/new-graph/js/yui/assets/menuarodwn9_clk_1.gif new file mode 100644 index 00000000000..65d7929b00d Binary files /dev/null and b/webtools/new-graph/js/yui/assets/menuarodwn9_clk_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/menuarodwn9_dim_1.gif b/webtools/new-graph/js/yui/assets/menuarodwn9_dim_1.gif new file mode 100644 index 00000000000..028adad3772 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/menuarodwn9_dim_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/menuarodwn9_nrm_1.gif b/webtools/new-graph/js/yui/assets/menuarodwn9_nrm_1.gif new file mode 100644 index 00000000000..a3f075753ed Binary files /dev/null and b/webtools/new-graph/js/yui/assets/menuarodwn9_nrm_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/menuarorght9_dim_1.gif b/webtools/new-graph/js/yui/assets/menuarorght9_dim_1.gif new file mode 100644 index 00000000000..59c6389120d Binary files /dev/null and b/webtools/new-graph/js/yui/assets/menuarorght9_dim_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/menuarorght9_hov_1.gif b/webtools/new-graph/js/yui/assets/menuarorght9_hov_1.gif new file mode 100644 index 00000000000..7042ae668f2 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/menuarorght9_hov_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/menuarorght9_nrm_1.gif b/webtools/new-graph/js/yui/assets/menuarorght9_nrm_1.gif new file mode 100644 index 00000000000..acd7f20ec3d Binary files /dev/null and b/webtools/new-graph/js/yui/assets/menuarorght9_nrm_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/tip16_1.gif b/webtools/new-graph/js/yui/assets/tip16_1.gif new file mode 100644 index 00000000000..8f0be2b8d1f Binary files /dev/null and b/webtools/new-graph/js/yui/assets/tip16_1.gif differ diff --git a/webtools/new-graph/js/yui/assets/tm.gif b/webtools/new-graph/js/yui/assets/tm.gif new file mode 100644 index 00000000000..e30abad8900 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/tm.gif differ diff --git a/webtools/new-graph/js/yui/assets/tmh.gif b/webtools/new-graph/js/yui/assets/tmh.gif new file mode 100644 index 00000000000..ad7e5579378 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/tmh.gif differ diff --git a/webtools/new-graph/js/yui/assets/tn.gif b/webtools/new-graph/js/yui/assets/tn.gif new file mode 100644 index 00000000000..4a280397de0 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/tn.gif differ diff --git a/webtools/new-graph/js/yui/assets/tp.gif b/webtools/new-graph/js/yui/assets/tp.gif new file mode 100644 index 00000000000..d6d0ed0aed4 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/tp.gif differ diff --git a/webtools/new-graph/js/yui/assets/tph.gif b/webtools/new-graph/js/yui/assets/tph.gif new file mode 100644 index 00000000000..e4d7d991e44 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/tph.gif differ diff --git a/webtools/new-graph/js/yui/assets/tree.css b/webtools/new-graph/js/yui/assets/tree.css new file mode 100644 index 00000000000..dffca1eb42b --- /dev/null +++ b/webtools/new-graph/js/yui/assets/tree.css @@ -0,0 +1,98 @@ +/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ + +/* first or middle sibling, no children */ +.ygtvtn { + width:16px; height:22px; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/tn.gif) 0 0 no-repeat; +} + +/* first or middle sibling, collapsable */ +.ygtvtm { + width:16px; height:22px; + cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/tm.gif) 0 0 no-repeat; +} + +/* first or middle sibling, collapsable, hover */ +.ygtvtmh { + width:16px; height:22px; + cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/tmh.gif) 0 0 no-repeat; +} + +/* first or middle sibling, expandable */ +.ygtvtp { + width:16px; height:22px; + cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/tp.gif) 0 0 no-repeat; +} + +/* first or middle sibling, expandable, hover */ +.ygtvtph { + width:16px; height:22px; + cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/tph.gif) 0 0 no-repeat; +} + +/* last sibling, no children */ +.ygtvln { + width:16px; height:22px; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/ln.gif) 0 0 no-repeat; +} + +/* Last sibling, collapsable */ +.ygtvlm { + width:16px; height:22px; + cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/lm.gif) 0 0 no-repeat; +} + +/* Last sibling, collapsable, hover */ +.ygtvlmh { + width:16px; height:22px; + cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/lmh.gif) 0 0 no-repeat; +} + +/* Last sibling, expandable */ +.ygtvlp { + width:16px; height:22px; + cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/lp.gif) 0 0 no-repeat; +} + +/* Last sibling, expandable, hover */ +.ygtvlph { + width:16px; height:22px; cursor:pointer ; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/lph.gif) 0 0 no-repeat; +} + +/* Loading icon */ +.ygtvloading { + width:16px; height:22px; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/loading.gif) 0 0 no-repeat; +} + +/* the style for the empty cells that are used for rendering the depth + * of the node */ +.ygtvdepthcell { + width:16px; height:22px; + background: url(../../../../../../../i/us/nt/widg/tree/dflt/vline.gif) 0 0 no-repeat; +} + +.ygtvblankdepthcell { width:16px; height:22px; } + +/* the style of the div around each node */ +.ygtvitem { } + +/* the style of the div around each node's collection of children */ +.ygtvchildren { } +* html .ygtvchildren { height:2%; } + +/* the style of the text label in ygTextNode */ +.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover { + margin-left:2px; + text-decoration: none; +} + +.ygtvspacer { height: 10px; width: 10px; margin: 2px; } diff --git a/webtools/new-graph/js/yui/assets/vline.gif b/webtools/new-graph/js/yui/assets/vline.gif new file mode 100644 index 00000000000..1fb0de8bb29 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/vline.gif differ diff --git a/webtools/new-graph/js/yui/assets/warn16_1.gif b/webtools/new-graph/js/yui/assets/warn16_1.gif new file mode 100644 index 00000000000..d679df5aae9 Binary files /dev/null and b/webtools/new-graph/js/yui/assets/warn16_1.gif differ diff --git a/webtools/new-graph/js/yui/autocomplete.js b/webtools/new-graph/js/yui/autocomplete.js new file mode 100644 index 00000000000..b8613e22f23 --- /dev/null +++ b/webtools/new-graph/js/yui/autocomplete.js @@ -0,0 +1,135 @@ + +YAHOO.widget.AutoComplete=function(inputEl,containerEl,oDataSource,oConfigs){if(inputEl&&containerEl&&oDataSource){if(oDataSource.getResults){this.dataSource=oDataSource;} +else{return;} +if(YAHOO.util.Dom.inDocument(inputEl)){if(typeof inputEl=="string"){this._sName=inputEl+YAHOO.widget.AutoComplete._nIndex;this._oTextbox=document.getElementById(inputEl);} +else{this._sName=(inputEl.id)?inputEl.id+YAHOO.widget.AutoComplete._nIndex:"yac_inputEl"+YAHOO.widget.AutoComplete._nIndex;this._oTextbox=inputEl;}} +else{return;} +if(YAHOO.util.Dom.inDocument(containerEl)){if(typeof containerEl=="string"){this._oContainer=document.getElementById(containerEl);} +else{this._oContainer=containerEl;}} +else{return;} +if(typeof oConfigs=="object"){for(var sConfig in oConfigs){if(sConfig){this[sConfig]=oConfigs[sConfig];}}} +var oSelf=this;var oTextbox=this._oTextbox;var oContainer=this._oContainer;YAHOO.util.Event.addListener(oTextbox,'keyup',oSelf._onTextboxKeyUp,oSelf);YAHOO.util.Event.addListener(oTextbox,'keydown',oSelf._onTextboxKeyDown,oSelf);YAHOO.util.Event.addListener(oTextbox,'keypress',oSelf._onTextboxKeyPress,oSelf);YAHOO.util.Event.addListener(oTextbox,'focus',oSelf._onTextboxFocus,oSelf);YAHOO.util.Event.addListener(oTextbox,'blur',oSelf._onTextboxBlur,oSelf);YAHOO.util.Event.addListener(oContainer,'mouseover',oSelf._onContainerMouseover,oSelf);YAHOO.util.Event.addListener(oContainer,'mouseout',oSelf._onContainerMouseout,oSelf);YAHOO.util.Event.addListener(oContainer,'scroll',oSelf._onContainerScroll,oSelf);if(oTextbox.form&&this.allowBrowserAutocomplete){YAHOO.util.Event.addListener(oTextbox.form,'submit',oSelf._onFormSubmit,oSelf);} +this.textboxFocusEvent=new YAHOO.util.CustomEvent("textboxFocus",this);this.textboxKeyEvent=new YAHOO.util.CustomEvent("textboxKey",this);this.dataRequestEvent=new YAHOO.util.CustomEvent("dataRequest",this);this.dataReturnEvent=new YAHOO.util.CustomEvent("dataReturn",this);this.dataErrorEvent=new YAHOO.util.CustomEvent("dataError",this);this.containerExpandEvent=new YAHOO.util.CustomEvent("containerExpand",this);this.typeAheadEvent=new YAHOO.util.CustomEvent("typeAhead",this);this.itemMouseOverEvent=new YAHOO.util.CustomEvent("itemMouseOver",this);this.itemMouseOutEvent=new YAHOO.util.CustomEvent("itemMouseOut",this);this.itemArrowToEvent=new YAHOO.util.CustomEvent("itemArrowTo",this);this.itemArrowFromEvent=new YAHOO.util.CustomEvent("itemArrowFrom",this);this.itemSelectEvent=new YAHOO.util.CustomEvent("itemSelect",this);this.selectionEnforceEvent=new YAHOO.util.CustomEvent("selectionEnforce",this);this.containerCollapseEvent=new YAHOO.util.CustomEvent("containerCollapse",this);this.textboxBlurEvent=new YAHOO.util.CustomEvent("textboxBlur",this);oTextbox.setAttribute("autocomplete","off");this._initProps();} +else{}};YAHOO.widget.AutoComplete.prototype.dataSource=null;YAHOO.widget.AutoComplete.prototype.minQueryLength=1;YAHOO.widget.AutoComplete.prototype.maxResultsDisplayed=10;YAHOO.widget.AutoComplete.prototype.queryDelay=0.5;YAHOO.widget.AutoComplete.prototype.highlightClassName="highlight";YAHOO.widget.AutoComplete.prototype.delimChar=null;YAHOO.widget.AutoComplete.prototype.typeAhead=false;YAHOO.widget.AutoComplete.prototype.animHoriz=false;YAHOO.widget.AutoComplete.prototype.animVert=true;YAHOO.widget.AutoComplete.prototype.animSpeed=0.3;YAHOO.widget.AutoComplete.prototype.forceSelection=false;YAHOO.widget.AutoComplete.prototype.allowBrowserAutocomplete=true;YAHOO.widget.AutoComplete.prototype.getName=function(){return this._sName;};YAHOO.widget.AutoComplete.prototype.getListIds=function(){return this._aListIds;};YAHOO.widget.AutoComplete.prototype.setHeader=function(sHeader){if(sHeader){this._oHeader.innerHTML=sHeader;this._oHeader.style.display="block";}};YAHOO.widget.AutoComplete.prototype.setFooter=function(sFooter){if(sFooter){this._oFooter.innerHTML=sFooter;this._oFooter.style.display="block";}};YAHOO.widget.AutoComplete.prototype.useIFrame=false;YAHOO.widget.AutoComplete.prototype.formatResult=function(oResultItem,sQuery){var sResult=oResultItem[0];if(sResult){return sResult;} +else{return"";}};YAHOO.widget.AutoComplete.prototype.textboxFocusEvent=null;YAHOO.widget.AutoComplete.prototype.textboxKeyEvent=null;YAHOO.widget.AutoComplete.prototype.dataRequestEvent=null;YAHOO.widget.AutoComplete.prototype.dataReturnEvent=null;YAHOO.widget.AutoComplete.prototype.dataErrorEvent=null;YAHOO.widget.AutoComplete.prototype.containerExpandEvent=null;YAHOO.widget.AutoComplete.prototype.typeAheadEvent=null;YAHOO.widget.AutoComplete.prototype.itemMouseOverEvent=null;YAHOO.widget.AutoComplete.prototype.itemMouseOutEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowToEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowFromEvent=null;YAHOO.widget.AutoComplete.prototype.itemSelectEvent=null;YAHOO.widget.AutoComplete.prototype.selectionEnforceEvent=null;YAHOO.widget.AutoComplete.prototype.containerCollapseEvent=null;YAHOO.widget.AutoComplete.prototype.textboxBlurEvent=null;YAHOO.widget.AutoComplete._nIndex=0;YAHOO.widget.AutoComplete.prototype._sName=null;YAHOO.widget.AutoComplete.prototype._oTextbox=null;YAHOO.widget.AutoComplete.prototype._bFocused=true;YAHOO.widget.AutoComplete.prototype._oAnim=null;YAHOO.widget.AutoComplete.prototype._oContainer=null;YAHOO.widget.AutoComplete.prototype._bContainerOpen=false;YAHOO.widget.AutoComplete.prototype._bOverContainer=false;YAHOO.widget.AutoComplete.prototype._oIFrame=null;YAHOO.widget.AutoComplete.prototype._oContent=null;YAHOO.widget.AutoComplete.prototype._oHeader=null;YAHOO.widget.AutoComplete.prototype._oFooter=null;YAHOO.widget.AutoComplete.prototype._aListIds=null;YAHOO.widget.AutoComplete.prototype._nDisplayedItems=0;YAHOO.widget.AutoComplete.prototype._sCurQuery=null;YAHOO.widget.AutoComplete.prototype._sSavedQuery=null;YAHOO.widget.AutoComplete.prototype._oCurItem=null;YAHOO.widget.AutoComplete.prototype._bItemSelected=false;YAHOO.widget.AutoComplete.prototype._nKeyCode=null;YAHOO.widget.AutoComplete.prototype._nDelayID=-1;YAHOO.widget.AutoComplete.prototype._initProps=function(){var minQueryLength=this.minQueryLength;if(isNaN(minQueryLength)||(minQueryLength<1)){minQueryLength=1;} +var maxResultsDisplayed=this.maxResultsDisplayed;if(isNaN(this.maxResultsDisplayed)||(this.maxResultsDisplayed<1)){this.maxResultsDisplayed=10;} +var queryDelay=this.queryDelay;if(isNaN(this.queryDelay)||(this.queryDelay<0)){this.queryDelay=0.5;} +var aDelimChar=(this.delimChar)?this.delimChar:null;if(aDelimChar){if(typeof aDelimChar=="string"){this.delimChar=[aDelimChar];} +else if(aDelimChar.constructor!=Array){this.delimChar=null;}} +var animSpeed=this.animSpeed;if(this.animHoriz||this.animVert){if(isNaN(animSpeed)||(animSpeed<0)){animSpeed=0.3;} +if(!this._oAnim&&YAHOO.util.Anim){this._oAnim=new YAHOO.util.Anim(this._oContainer,{},animSpeed);} +else if(this._oAnim){this._oAnim.duration=animSpeed;}} +if(this.forceSelection&&this.delimChar){} +if(!this._aListIds){this._aListIds=[];} +if(!this._aListIds||(this.maxResultsDisplayed!=this._aListIds.length)){this._initContainer();}};YAHOO.widget.AutoComplete.prototype._initContainer=function(){this._aListIds=[];var aItemsMarkup=[];var sName=this._sName;var sPrefix=sName+"item";var sHeaderID=sName+"header";var sFooterID=sName+"footer";for(var i=this.maxResultsDisplayed-1;i>=0;i--){var sItemID=sPrefix+i;this._aListIds[i]=sItemID;aItemsMarkup.unshift("
  • \n");} +var sList="
      "+ +aItemsMarkup.join("")+"
    ";var sContent=(this.useIFrame)?["
    ","
    ",sList,"
    ","
    "]:["
    ",sList,"
    "];sContent=sContent.join("");this._oContainer.innerHTML=sContent;this._oHeader=document.getElementById(sHeaderID);this._oFooter=document.getElementById(sFooterID);if(this.useIFrame){this._oContent=document.getElementById(sName+"content");this._oIFrame=document.getElementById(sName+"iframe");this._oContent.style.position="relative";this._oIFrame.style.position="relative";this._oContent.style.zIndex=9050;} +this._oContainer.style.display="none";this._oHeader.style.display="none";this._oFooter.style.display="none";this._initItems();};YAHOO.widget.AutoComplete.prototype._initItems=function(){for(var i=this.maxResultsDisplayed-1;i>=0;i--){var oItem=document.getElementById(this._aListIds[i]);this._initItem(oItem,i);}};YAHOO.widget.AutoComplete.prototype._initItem=function(oItem,nItemIndex){var oSelf=this;oItem.style.display="none";oItem._nItemIndex=nItemIndex;oItem.mouseover=oItem.mouseout=oItem.onclick=null;YAHOO.util.Event.addListener(oItem,'mouseover',oSelf._onItemMouseover,oSelf);YAHOO.util.Event.addListener(oItem,'mouseout',oSelf._onItemMouseout,oSelf);YAHOO.util.Event.addListener(oItem,'click',oSelf._onItemMouseclick,oSelf);};YAHOO.widget.AutoComplete.prototype._onItemMouseover=function(v,oSelf){oSelf._toggleHighlight(this,'mouseover');oSelf.itemMouseOverEvent.fire(oSelf,this);};YAHOO.widget.AutoComplete.prototype._onItemMouseout=function(v,oSelf){oSelf._toggleHighlight(this,'mouseout');oSelf.itemMouseOutEvent.fire(oSelf,this);};YAHOO.widget.AutoComplete.prototype._onItemMouseclick=function(v,oSelf){oSelf._toggleHighlight(this,'mouseover');oSelf._selectItem(this);};YAHOO.widget.AutoComplete.prototype._onContainerMouseover=function(v,oSelf){oSelf._bOverContainer=true;};YAHOO.widget.AutoComplete.prototype._onContainerMouseout=function(v,oSelf){oSelf._bOverContainer=false;if(oSelf._oCurItem){oSelf._toggleHighlight(oSelf._oCurItem,'mouseover');}};YAHOO.widget.AutoComplete.prototype._onContainerScroll=function(v,oSelf){oSelf._oTextbox.focus();};YAHOO.widget.AutoComplete.prototype._onTextboxKeyDown=function(v,oSelf){var nKeyCode=v.keyCode;switch(nKeyCode){case 9:if(oSelf.delimChar&&(oSelf._nKeyCode!=nKeyCode)){if(oSelf._bContainerOpen){YAHOO.util.Event.stopEvent(v);}} +if(oSelf._oCurItem){oSelf._selectItem(oSelf._oCurItem);} +else{oSelf._clearList();} +break;case 13:if(oSelf._nKeyCode!=nKeyCode){if(oSelf._bContainerOpen){YAHOO.util.Event.stopEvent(v);}} +if(oSelf._oCurItem){oSelf._selectItem(oSelf._oCurItem);} +else{oSelf._clearList();} +break;case 27:oSelf._clearList();return;case 39:oSelf._jumpSelection();break;case 38:YAHOO.util.Event.stopEvent(v);oSelf._moveSelection(nKeyCode);break;case 40:YAHOO.util.Event.stopEvent(v);oSelf._moveSelection(nKeyCode);break;default:break;}};YAHOO.widget.AutoComplete.prototype._onTextboxKeyPress=function(v,oSelf){var nKeyCode=v.keyCode;switch(nKeyCode){case 9:case 13:if(oSelf.delimChar&&(oSelf._nKeyCode!=nKeyCode)){if(oSelf._bContainerOpen){YAHOO.util.Event.stopEvent(v);}} +break;case 38:case 40:YAHOO.util.Event.stopEvent(v);break;default:break;}};YAHOO.widget.AutoComplete.prototype._onTextboxKeyUp=function(v,oSelf){oSelf._initProps();var nKeyCode=v.keyCode;oSelf._nKeyCode=nKeyCode;var sChar=String.fromCharCode(nKeyCode);var sText=this.value;if(oSelf._isIgnoreKey(nKeyCode)||(sText.toLowerCase()==this._sCurQuery)){return;} +else{oSelf.textboxKeyEvent.fire(oSelf,nKeyCode);} +if(oSelf.queryDelay>0){var nDelayID=setTimeout(function(){oSelf._sendQuery(sText);},(oSelf.queryDelay*1000));if(oSelf._nDelayID!=-1){clearTimeout(oSelf._nDelayID);} +oSelf._nDelayID=nDelayID;} +else{oSelf._sendQuery(sText);}};YAHOO.widget.AutoComplete.prototype._isIgnoreKey=function(nKeyCode){if(this.typeAhead){if((nKeyCode==8)||(nKeyCode==39)||(nKeyCode==46)){return true;}} +if((nKeyCode==9)||(nKeyCode==13)||(nKeyCode==16)||(nKeyCode==17)||(nKeyCode>=18&&nKeyCode<=20)||(nKeyCode==27)||(nKeyCode>=33&&nKeyCode<=35)||(nKeyCode>=36&&nKeyCode<=38)||(nKeyCode==40)||(nKeyCode>=44&&nKeyCode<=45)){return true;} +return false;};YAHOO.widget.AutoComplete.prototype._onTextboxFocus=function(v,oSelf){oSelf._oTextbox.setAttribute("autocomplete","off");oSelf._bFocused=true;oSelf.textboxFocusEvent.fire(oSelf);};YAHOO.widget.AutoComplete.prototype._onTextboxBlur=function(v,oSelf){if(!oSelf._bOverContainer||(oSelf._nKeyCode==9)){if(oSelf.forceSelection&&!oSelf._bItemSelected){if(!oSelf._bContainerOpen||(oSelf._bContainerOpen&&!oSelf._textMatchesOption())){oSelf._clearSelection();}} +if(oSelf._bContainerOpen){oSelf._clearList();} +oSelf._bFocused=false;oSelf.textboxBlurEvent.fire(oSelf);}};YAHOO.widget.AutoComplete.prototype._onFormSubmit=function(v,oSelf){oSelf._oTextbox.setAttribute("autocomplete","on");};YAHOO.widget.AutoComplete.prototype._sendQuery=function(sQuery){var aDelimChar=(this.delimChar)?this.delimChar:null;if(aDelimChar){var nDelimIndex=-1;for(var i=aDelimChar.length-1;i>=0;i--){var nNewIndex=sQuery.lastIndexOf(aDelimChar[i]);if(nNewIndex>nDelimIndex){nDelimIndex=nNewIndex;}} +if(aDelimChar[i]==" "){for(var j=aDelimChar.length-1;j>=0;j--){if(sQuery[nDelimIndex-1]==aDelimChar[j]){nDelimIndex--;break;}}} +if(nDelimIndex>-1){var nQueryStart=nDelimIndex+1;while(sQuery.charAt(nQueryStart)==" "){nQueryStart+=1;} +this._sSavedQuery=sQuery.substring(0,nQueryStart);sQuery=sQuery.substr(nQueryStart);} +else if(sQuery.indexOf(this._sSavedQuery)<0){this._sSavedQuery=null;}} +if(sQuery.length=0;i--){document.getElementById(aItems[i]).style.display="none";} +if(this._oCurItem){this._toggleHighlight(this._oCurItem,'mouseout');} +this._oCurItem=null;this._nDisplayedItems=0;this._sCurQuery=null;this._toggleContainer(false);};YAHOO.widget.AutoComplete.prototype._populateList=function(sQuery,aResults,oSelf){if(aResults===null){oSelf.dataErrorEvent.fire(oSelf,sQuery);} +else{oSelf.dataReturnEvent.fire(oSelf,sQuery,aResults);} +if(!oSelf._bFocused||!aResults){return;} +var isOpera=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);oSelf._oContainer.style.width=(!isOpera)?null:"";oSelf._oContainer.style.height=(!isOpera)?null:"";var sCurQuery=decodeURI(sQuery);oSelf._sCurQuery=sCurQuery;var aItems=oSelf._aListIds;oSelf._bItemSelected=false;var nItems=Math.min(aResults.length,oSelf.maxResultsDisplayed);oSelf._nDisplayedItems=nItems;if(nItems>0){for(var i=nItems-1;i>=0;i--){var oItemi=document.getElementById(aItems[i]);var oResultItemi=aResults[i];oItemi.innerHTML=oSelf.formatResult(oResultItemi,sCurQuery);oItemi.style.display="list-item";oItemi._sResultKey=oResultItemi[0];oItemi._oResultData=oResultItemi;} +for(var j=aItems.length-1;j>=nItems;j--){var oItemj=document.getElementById(aItems[j]);oItemj.innerHTML=null;oItemj.style.display="none";oItemj._sResultKey=null;oItemj._oResultData=null;} +var oFirstItem=document.getElementById(aItems[0]);oSelf._toggleHighlight(oFirstItem,'mouseover');oSelf._toggleContainer(true);oSelf.itemArrowToEvent.fire(oSelf,oFirstItem);oSelf._typeAhead(oFirstItem,sQuery);oSelf._oCurItem=oFirstItem;} +else{oSelf._clearList();}};YAHOO.widget.AutoComplete.prototype._clearSelection=function(){var sValue=this._oTextbox.value;var sChar=(this.delimChar)?this.delimChar[0]:null;var nIndex=(sChar)?sValue.lastIndexOf(sChar,sValue.length-2):-1;if(nIndex>-1){this._oTextbox.value=sValue.substring(0,nIndex);} +else{this._oTextbox.value="";} +this._sSavedQuery=this._oTextbox.value;this.selectionEnforceEvent.fire(this);};YAHOO.widget.AutoComplete.prototype._textMatchesOption=function(){var foundMatch=false;for(var i=this._nDisplayedItems-1;i>=0;i--){var oItem=document.getElementById(this._aListIds[i]);var sMatch=oItem._sResultKey.toLowerCase();if(sMatch==this._sCurQuery.toLowerCase()){foundMatch=true;break;}} +return(foundMatch);};YAHOO.widget.AutoComplete.prototype._typeAhead=function(oItem,sQuery){var oTextbox=this._oTextbox;var sValue=this._oTextbox.value;if(!this.typeAhead){return;} +if(!oTextbox.setSelectionRange&&!oTextbox.createTextRange){return;} +var nStart=sValue.length;this._updateValue(oItem);var nEnd=oTextbox.value.length;this._selectText(oTextbox,nStart,nEnd);var sPrefill=oTextbox.value.substr(nStart,nEnd);this.typeAheadEvent.fire(this,sQuery,sPrefill);};YAHOO.widget.AutoComplete.prototype._selectText=function(oTextbox,nStart,nEnd){if(oTextbox.setSelectionRange){oTextbox.setSelectionRange(nStart,nEnd);} +else if(oTextbox.createTextRange){var oTextRange=oTextbox.createTextRange();oTextRange.moveStart("character",nStart);oTextRange.moveEnd("character",nEnd-oTextbox.value.length);oTextRange.select();} +else{oTextbox.select();}};YAHOO.widget.AutoComplete.prototype._toggleContainer=function(bShow){var oContainer=this._oContainer;if(!bShow&&!this._bContainerOpen){oContainer.style.display="none";return;} +var oContent=this._oContent;var oIFrame=this._oIFrame;if(bShow&&oContent&&oIFrame){var sDisplay=oContainer.style.display;oContainer.style.display="block";oIFrame.style.width=oContent.offsetWidth+"px";oIFrame.style.height=oContent.offsetHeight+"px";oIFrame.style.marginTop="-"+oContent.offsetHeight+"px";oContainer.style.display=sDisplay;} +var oAnim=this._oAnim;if(oAnim&&oAnim.getEl()&&(this.animHoriz||this.animVert)){if(oAnim.isAnimated()){oAnim.stop();} +var oClone=oContainer.cloneNode(true);oContainer.parentNode.appendChild(oClone);oClone.style.top="-9000px";oClone.style.display="block";var wExp=oClone.offsetWidth;var hExp=oClone.offsetHeight;var wColl=(this.animHoriz)?0:wExp;var hColl=(this.animVert)?0:hExp;oAnim.attributes=(bShow)?{width:{to:wExp},height:{to:hExp}}:{width:{to:wColl},height:{to:hColl}};if(bShow&&!this._bContainerOpen){oContainer.style.width=wColl+"px";oContainer.style.height=hColl+"px";} +else{oContainer.style.width=wExp+"px";oContainer.style.height=hExp+"px";} +oContainer.parentNode.removeChild(oClone);oClone=null;var oSelf=this;var onAnimComplete=function(){if(!bShow){oContainer.style.display="none";} +oAnim.onComplete.unsubscribeAll();if(bShow){oSelf.containerExpandEvent.fire(oSelf);} +else{oSelf.containerCollapseEvent.fire(oSelf);}};oContainer.style.display="block";oAnim.onComplete.subscribe(onAnimComplete);oAnim.animate();this._bContainerOpen=bShow;} +else{this._bContainerOpen=bShow;oContainer.style.display=(bShow)?"block":"none";if(bShow){this.containerExpandEvent.fire(this);} +else{this.containerCollapseEvent.fire(this);}}};YAHOO.widget.AutoComplete.prototype._toggleHighlight=function(oNewItem,sType){oNewItem.className=oNewItem.className.replace(this.highlightClassName,"");if(this._oCurItem){this._oCurItem.className=this._oCurItem.className.replace(this.highlightClassName,"");} +if(sType=='mouseover'){oNewItem.className+=" "+this.highlightClassName;this._oCurItem=oNewItem;}};YAHOO.widget.AutoComplete.prototype._updateValue=function(oItem){var oTextbox=this._oTextbox;var sDelimChar=(this.delimChar)?this.delimChar[0]:null;var sSavedQuery=this._sSavedQuery;var sResultKey=oItem._sResultKey;oTextbox.focus();oTextbox.value="";if(sDelimChar){if(sSavedQuery){oTextbox.value=sSavedQuery;} +oTextbox.value+=sResultKey+sDelimChar;if(sDelimChar!=" "){oTextbox.value+=" ";}} +else{oTextbox.value=sResultKey;} +if(oTextbox.type=="textarea"){oTextbox.scrollTop=oTextbox.scrollHeight;} +var end=oTextbox.value.length;this._selectText(oTextbox,end,end);this._oCurItem=oItem;};YAHOO.widget.AutoComplete.prototype._selectItem=function(oItem){this._bItemSelected=true;this._updateValue(oItem);this.itemSelectEvent.fire(this,oItem);this._clearList();};YAHOO.widget.AutoComplete.prototype._jumpSelection=function(){if(!this.typeAhead){return;} +else{this._clearList();}};YAHOO.widget.AutoComplete.prototype._moveSelection=function(nKeyCode){if(this._bContainerOpen){var oCurItem=this._oCurItem;var nCurItemIndex=-1;if(oCurItem){nCurItemIndex=oCurItem._nItemIndex;} +var nNewItemIndex=(nKeyCode==40)?(nCurItemIndex+1):(nCurItemIndex-1);if(nNewItemIndex<-2||nNewItemIndex>=this._nDisplayedItems){return;} +if(oCurItem){this._toggleHighlight(oCurItem,'mouseout');this.itemArrowFromEvent.fire(this,oCurItem);} +if(nNewItemIndex==-1){if(this.delimChar&&this._sSavedQuery){if(!this._textMatchesOption()){this._oTextbox.value=this._sSavedQuery;} +else{this._oTextbox.value=this._sSavedQuery+this._sCurQuery;}} +else{this._oTextbox.value=this._sCurQuery;} +this._oCurItem=null;return;} +if(nNewItemIndex==-2){this._clearList();return;} +var oNewItem=document.getElementById(this._sName+"item"+nNewItemIndex);if((YAHOO.util.Dom.getStyle(this._oContainer,"overflow")=="auto")&&(nNewItemIndex>-1)&&(nNewItemIndex(this._oContainer.scrollTop+this._oContainer.offsetHeight)){this._oContainer.scrollTop=(oNewItem.offsetTop+oNewItem.offsetHeight)-this._oContainer.offsetHeight;} +else if((oNewItem.offsetTop+oNewItem.offsetHeight)(this._oContainer.scrollTop+this._oContainer.offsetHeight)){this._oContainer.scrollTop=(oNewItem.offsetTop+oNewItem.offsetHeight)-this._oContainer.offsetHeight;}}} +this._toggleHighlight(oNewItem,'mouseover');this.itemArrowToEvent.fire(this,oNewItem);if(this.typeAhead){this._updateValue(oNewItem);}}};YAHOO.widget.DataSource=function(){};YAHOO.widget.DataSource.prototype.ERROR_DATANULL="Response data was null";YAHOO.widget.DataSource.prototype.ERROR_DATAPARSE="Response data could not be parsed";YAHOO.widget.DataSource.prototype.maxCacheEntries=15;YAHOO.widget.DataSource.prototype.queryMatchContains=false;YAHOO.widget.DataSource.prototype.queryMatchSubset=false;YAHOO.widget.DataSource.prototype.queryMatchCase=false;YAHOO.widget.DataSource.prototype.getResults=function(oCallbackFn,sQuery,oParent){var aResults=this._doQueryCache(oCallbackFn,sQuery,oParent);if(aResults.length===0){this.queryEvent.fire(this,oParent,sQuery);this.doQuery(oCallbackFn,sQuery,oParent);}};YAHOO.widget.DataSource.prototype.doQuery=function(oCallbackFn,sQuery,oParent){};YAHOO.widget.DataSource.prototype.flushCache=function(){if(this._aCache){this._aCache=[];} +if(this._aCacheHelper){this._aCacheHelper=[];} +this.cacheFlushEvent.fire(this);};YAHOO.widget.DataSource.prototype.queryEvent=null;YAHOO.widget.DataSource.prototype.cacheQueryEvent=null;YAHOO.widget.DataSource.prototype.getResultsEvent=null;YAHOO.widget.DataSource.prototype.getCachedResultsEvent=null;YAHOO.widget.DataSource.prototype.dataErrorEvent=null;YAHOO.widget.DataSource.prototype.cacheFlushEvent=null;YAHOO.widget.DataSource.prototype._aCache=null;YAHOO.widget.DataSource.prototype._init=function(){var maxCacheEntries=this.maxCacheEntries;if(isNaN(maxCacheEntries)||(maxCacheEntries<0)){maxCacheEntries=0;} +if(maxCacheEntries>0&&!this._aCache){this._aCache=[];} +this.queryEvent=new YAHOO.util.CustomEvent("query",this);this.cacheQueryEvent=new YAHOO.util.CustomEvent("cacheQuery",this);this.getResultsEvent=new YAHOO.util.CustomEvent("getResults",this);this.getCachedResultsEvent=new YAHOO.util.CustomEvent("getCachedResults",this);this.dataErrorEvent=new YAHOO.util.CustomEvent("dataError",this);this.cacheFlushEvent=new YAHOO.util.CustomEvent("cacheFlush",this);};YAHOO.widget.DataSource.prototype._addCacheElem=function(resultObj){var aCache=this._aCache;if(!aCache||!resultObj||!resultObj.query||!resultObj.results){return;} +if(aCache.length>=this.maxCacheEntries){aCache.shift();} +aCache.push(resultObj);};YAHOO.widget.DataSource.prototype._doQueryCache=function(oCallbackFn,sQuery,oParent){var aResults=[];var bMatchFound=false;var aCache=this._aCache;var nCacheLength=(aCache)?aCache.length:0;var bMatchContains=this.queryMatchContains;if((this.maxCacheEntries>0)&&aCache&&(nCacheLength>0)){this.cacheQueryEvent.fire(this,oParent,sQuery);if(!this.queryMatchCase){var sOrigQuery=sQuery;sQuery=sQuery.toLowerCase();} +for(var i=nCacheLength-1;i>=0;i--){var resultObj=aCache[i];var aAllResultItems=resultObj.results;var matchKey=(!this.queryMatchCase)?encodeURI(resultObj.query.toLowerCase()):encodeURI(resultObj.query);if(matchKey==sQuery){bMatchFound=true;aResults=aAllResultItems;if(i!=nCacheLength-1){aCache.splice(i,1);this._addCacheElem(resultObj);} +break;} +else if(this.queryMatchSubset){for(var j=sQuery.length-1;j>=0;j--){var subQuery=sQuery.substr(0,j);if(matchKey==subQuery){bMatchFound=true;for(var k=aAllResultItems.length-1;k>=0;k--){var aRecord=aAllResultItems[k];var sKeyIndex=(this.queryMatchCase)?encodeURI(aRecord[0]).indexOf(sQuery):encodeURI(aRecord[0]).toLowerCase().indexOf(sQuery);if((!bMatchContains&&(sKeyIndex===0))||(bMatchContains&&(sKeyIndex>-1))){aResults.unshift(aRecord);}} +resultObj={};resultObj.query=sQuery;resultObj.results=aResults;this._addCacheElem(resultObj);break;}} +if(bMatchFound){break;}}} +if(bMatchFound){this.getCachedResultsEvent.fire(this,oParent,sOrigQuery,aResults);oCallbackFn(sOrigQuery,aResults,oParent);}} +return aResults;};YAHOO.widget.DS_XHR=function(sScriptURI,aSchema,oConfigs){if(typeof oConfigs=="object"){for(var sConfig in oConfigs){this[sConfig]=oConfigs[sConfig];}} +if(!aSchema||(aSchema.constructor!=Array)){} +else{this.schema=aSchema;} +this.scriptURI=sScriptURI;this._init();};YAHOO.widget.DS_XHR.prototype=new YAHOO.widget.DataSource();YAHOO.widget.DS_XHR.prototype.TYPE_JSON=0;YAHOO.widget.DS_XHR.prototype.TYPE_XML=1;YAHOO.widget.DS_XHR.prototype.TYPE_FLAT=2;YAHOO.widget.DS_XHR.prototype.ERROR_DATAXHR="XHR response failed";YAHOO.widget.DS_XHR.prototype.scriptURI=null;YAHOO.widget.DS_XHR.prototype.scriptQueryParam="query";YAHOO.widget.DS_XHR.prototype.scriptQueryAppend="";YAHOO.widget.DS_XHR.prototype.responseType=YAHOO.widget.DS_XHR.prototype.TYPE_JSON;YAHOO.widget.DS_XHR.prototype.responseStripAfter="\n