Improve output: distinguish between failed assertions (failures) and unexpected exceptions (errors), and print a filtered stack trace for any exception.

This commit is contained in:
jeb228 2010-01-29 22:13:57 +00:00
commit 4f2e303079
1839 changed files with 235630 additions and 0 deletions

View file

@ -0,0 +1,72 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.AdapterRegistry");
dojo.require("dojo.lang.func");
dojo.AdapterRegistry = function(){
/***
A registry to facilitate adaptation.
Pairs is an array of [name, check, wrap] triples
All check/wrap functions in this registry should be of the same arity.
***/
this.pairs = [];
}
dojo.lang.extend(dojo.AdapterRegistry, {
register: function (name, check, wrap, /* optional */ override){
/***
The check function should return true if the given arguments are
appropriate for the wrap function.
If override is given and true, the check function will be given
highest priority. Otherwise, it will be the lowest priority
adapter.
***/
if (override) {
this.pairs.unshift([name, check, wrap]);
} else {
this.pairs.push([name, check, wrap]);
}
},
match: function (/* ... */) {
/***
Find an adapter for the given arguments.
If no suitable adapter is found, throws NotFound.
***/
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 new Error("No match found");
// dojo.raise("No match found");
},
unregister: function (name) {
/***
Remove a named adapter from the registry
***/
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;
}
});

309
webapp/web/src/Deferred.js Normal file
View file

@ -0,0 +1,309 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.Deferred");
dojo.require("dojo.lang.func");
dojo.Deferred = function(/* optional */ canceller){
/*
NOTE: this namespace and documentation are imported wholesale
from MochiKit
Encapsulates a sequence of callbacks in response to a value that
may not yet be available. This is modeled after the Deferred class
from Twisted <http://twistedmatrix.com>.
Why do we want this? JavaScript has no threads, and even if it did,
threads are hard. Deferreds are a way of abstracting non-blocking
events, such as the final response to an XMLHttpRequest.
The sequence of callbacks is internally represented as a list
of 2-tuples containing the callback/errback pair. For example,
the following call sequence::
var d = new Deferred();
d.addCallback(myCallback);
d.addErrback(myErrback);
d.addBoth(myBoth);
d.addCallbacks(myCallback, myErrback);
is translated into a Deferred with the following internal
representation::
[
[myCallback, null],
[null, myErrback],
[myBoth, myBoth],
[myCallback, myErrback]
]
The Deferred also keeps track of its current status (fired).
Its status may be one of three things:
-1: no value yet (initial condition)
0: success
1: error
A Deferred will be in the error state if one of the following
three conditions are met:
1. The result given to callback or errback is "instanceof" Error
2. The previous callback or errback raised an exception while
executing
3. The previous callback or errback returned a value "instanceof"
Error
Otherwise, the Deferred will be in the success state. The state of
the Deferred determines the next element in the callback sequence to
run.
When a callback or errback occurs with the example deferred chain,
something equivalent to the following will happen (imagine that
exceptions are caught and returned)::
// d.callback(result) or d.errback(result)
if(!(result instanceof Error)){
result = myCallback(result);
}
if(result instanceof Error){
result = myErrback(result);
}
result = myBoth(result);
if(result instanceof Error){
result = myErrback(result);
}else{
result = myCallback(result);
}
The result is then stored away in case another step is added to the
callback sequence. Since the Deferred already has a value available,
any new callbacks added will be called immediately.
There are two other "advanced" details about this implementation that
are useful:
Callbacks are allowed to return Deferred instances themselves, so you
can build complicated sequences of events with ease.
The creator of the Deferred may specify a canceller. The canceller
is a function that will be called if Deferred.cancel is called before
the Deferred fires. You can use this to implement clean aborting of
an XMLHttpRequest, etc. Note that cancel will fire the deferred with
a CancelledError (unless your canceller returns another kind of
error), so the errbacks should be prepared to handle that error for
cancellable Deferreds.
*/
this.chain = [];
this.id = this._nextId();
this.fired = -1;
this.paused = 0;
this.results = [null, null];
this.canceller = canceller;
this.silentlyCancelled = false;
};
dojo.lang.extend(dojo.Deferred, {
getFunctionFromArgs: function(){
var a = arguments;
if((a[0])&&(!a[1])){
if(dojo.lang.isFunction(a[0])){
return a[0];
}else if(dojo.lang.isString(a[0])){
return dj_global[a[0]];
}
}else if((a[0])&&(a[1])){
return dojo.lang.hitch(a[0], a[1]);
}
return null;
},
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: dojo.lang.forward("repr"),
_nextId: (function(){
var n = 1;
return function(){ return n++; };
})(),
cancel: function(){
/***
Cancels a Deferred that has not yet received a value, or is
waiting on another Deferred as its value.
If a canceller is defined, the canceller is called. If the
canceller did not return an error, or there was no canceller,
then the errback chain is started with CancelledError.
***/
if(this.fired == -1){
if (this.canceller){
this.canceller(this);
}else{
this.silentlyCancelled = true;
}
if(this.fired == -1){
this.errback(new Error(this.repr()));
}
}else if( (this.fired == 0)&&
(this.results[0] instanceof dojo.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){
dojo.raise("already called!");
}
this.silentlyCancelled = false;
return;
}
},
callback: function(res){
/*
Begin the callback sequence with a non-error value.
callback or errback should only be called once on a given
Deferred.
*/
this._check();
this._resback(res);
},
errback: function(res){
// Begin the callback sequence with an error result.
this._check();
if(!(res instanceof Error)){
res = new Error(res);
}
this._resback(res);
},
addBoth: function(cb, cbfn){
/*
Add the same function as both a callback and an errback as the
next element on the callback sequence. This is useful for code
that you want to guarantee to run, e.g. a finalizer.
*/
var enclosed = this.getFunctionFromArgs(cb, cbfn);
if(arguments.length > 2){
enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2);
}
return this.addCallbacks(enclosed, enclosed);
},
addCallback: function(cb, cbfn){
// Add a single callback to the end of the callback sequence.
var enclosed = this.getFunctionFromArgs(cb, cbfn);
if(arguments.length > 2){
enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2);
}
return this.addCallbacks(enclosed, null);
},
addErrback: function(cb, cbfn){
// Add a single callback to the end of the callback sequence.
var enclosed = this.getFunctionFromArgs(cb, cbfn);
if(arguments.length > 2){
enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2);
}
return this.addCallbacks(null, enclosed);
return this.addCallbacks(null, cbfn);
},
addCallbacks: function (cb, eb) {
// Add separate callback and errback to the end of the callback
// sequence.
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 dojo.Deferred) {
cb = function(res){
self._continue(res);
}
this._pause();
}
}catch(err){
fired = 1;
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);
}
}
});

View file

@ -0,0 +1,12 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation");
dojo.require("dojo.animation.Animation");

View file

@ -0,0 +1,217 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.Animation");
dojo.require("dojo.animation.AnimationEvent");
dojo.require("dojo.lang.func");
dojo.require("dojo.math");
dojo.require("dojo.math.curves");
/*
Animation package based off of Dan Pupius' work on Animations:
http://pupius.co.uk/js/Toolkit.Drawing.js
*/
dojo.animation.Animation = function(/*dojo.math.curves.Line*/ curve, /*int*/ duration, /*Decimal?*/ accel, /*int?*/ repeatCount, /*int?*/ rate) {
// public properties
if(dojo.lang.isArray(curve)) {
// curve: Array
// id: i
curve = new dojo.math.curves.Line(curve[0], curve[1]);
}
this.curve = curve;
this.duration = duration;
this.repeatCount = repeatCount || 0;
this.rate = rate || 25;
if(accel) {
// accel: Decimal
// id: j
if(dojo.lang.isFunction(accel.getValue)) {
// accel: dojo.math.curves.CatmullRom
// id: k
this.accel = accel;
} else {
var i = 0.35*accel+0.5; // 0.15 <= i <= 0.85
this.accel = new dojo.math.curves.CatmullRom([[0], [i], [1]], 0.45);
}
}
}
dojo.lang.extend(dojo.animation.Animation, {
// public properties
curve: null,
duration: 0,
repeatCount: 0,
accel: null,
// events
onBegin: null,
onAnimate: null,
onEnd: null,
onPlay: null,
onPause: null,
onStop: null,
handler: null,
// "private" properties
_animSequence: null,
_startTime: null,
_endTime: null,
_lastFrame: null,
_timer: null,
_percent: 0,
_active: false,
_paused: false,
_startRepeatCount: 0,
// public methods
play: function(gotoStart) {
if( gotoStart ) {
clearTimeout(this._timer);
this._active = false;
this._paused = false;
this._percent = 0;
} else if( this._active && !this._paused ) {
return;
}
this._startTime = new Date().valueOf();
if( this._paused ) {
this._startTime -= (this.duration * this._percent / 100);
}
this._endTime = this._startTime + this.duration;
this._lastFrame = this._startTime;
var e = new dojo.animation.AnimationEvent(this, null, this.curve.getValue(this._percent),
this._startTime, this._startTime, this._endTime, this.duration, this._percent, 0);
this._active = true;
this._paused = false;
if( this._percent == 0 ) {
if(!this._startRepeatCount) {
this._startRepeatCount = this.repeatCount;
}
e.type = "begin";
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onBegin == "function") { this.onBegin(e); }
}
e.type = "play";
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onPlay == "function") { this.onPlay(e); }
if(this._animSequence) { this._animSequence._setCurrent(this); }
this._cycle();
},
pause: function() {
clearTimeout(this._timer);
if( !this._active ) { return; }
this._paused = true;
var e = new dojo.animation.AnimationEvent(this, "pause", this.curve.getValue(this._percent),
this._startTime, new Date().valueOf(), this._endTime, this.duration, this._percent, 0);
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onPause == "function") { this.onPause(e); }
},
playPause: function() {
if( !this._active || this._paused ) {
this.play();
} else {
this.pause();
}
},
gotoPercent: function(pct, andPlay) {
clearTimeout(this._timer);
this._active = true;
this._paused = true;
this._percent = pct;
if( andPlay ) { this.play(); }
},
stop: function(gotoEnd) {
clearTimeout(this._timer);
var step = this._percent / 100;
if( gotoEnd ) {
step = 1;
}
var e = new dojo.animation.AnimationEvent(this, "stop", this.curve.getValue(step),
this._startTime, new Date().valueOf(), this._endTime, this.duration, this._percent);
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onStop == "function") { this.onStop(e); }
this._active = false;
this._paused = false;
},
status: function() {
if( this._active ) {
return this._paused ? "paused" : "playing";
} else {
return "stopped";
}
},
// "private" methods
_cycle: function() {
clearTimeout(this._timer);
if( this._active ) {
var curr = new Date().valueOf();
var step = (curr - this._startTime) / (this._endTime - this._startTime);
var fps = 1000 / (curr - this._lastFrame);
this._lastFrame = curr;
if( step >= 1 ) {
step = 1;
this._percent = 100;
} else {
this._percent = step * 100;
}
// Perform accelleration
if(this.accel && this.accel.getValue) {
step = this.accel.getValue(step);
}
var e = new dojo.animation.AnimationEvent(this, "animate", this.curve.getValue(step),
this._startTime, curr, this._endTime, this.duration, this._percent, Math.round(fps));
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onAnimate == "function") { this.onAnimate(e); }
if( step < 1 ) {
this._timer = setTimeout(dojo.lang.hitch(this, "_cycle"), this.rate);
} else {
e.type = "end";
this._active = false;
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onEnd == "function") { this.onEnd(e); }
if( this.repeatCount > 0 ) {
this.repeatCount--;
this.play(true);
} else if( this.repeatCount == -1 ) {
this.play(true);
} else {
if(this._startRepeatCount) {
this.repeatCount = this._startRepeatCount;
this._startRepeatCount = 0;
}
if( this._animSequence ) {
this._animSequence._playNext();
}
}
}
}
}
});

View file

@ -0,0 +1,40 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.AnimationEvent");
dojo.require("dojo.lang");
dojo.animation.AnimationEvent = function(anim, type, coords, sTime, cTime, eTime, dur, pct, fps) {
this.type = type; // "animate", "begin", "end", "play", "pause", "stop"
this.animation = anim;
this.coords = coords;
this.x = coords[0];
this.y = coords[1];
this.z = coords[2];
this.startTime = sTime;
this.currentTime = cTime;
this.endTime = eTime;
this.duration = dur;
this.percent = pct;
this.fps = fps;
};
dojo.lang.extend(dojo.animation.AnimationEvent, {
coordsAsInts: function() {
var cints = new Array(this.coords.length);
for(var i = 0; i < this.coords.length; i++) {
cints[i] = Math.round(this.coords[i]);
}
return cints;
}
});

View file

@ -0,0 +1,136 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.AnimationSequence");
dojo.require("dojo.animation.AnimationEvent");
dojo.require("dojo.animation.Animation");
dojo.animation.AnimationSequence = function(repeatCount){
this._anims = [];
this.repeatCount = repeatCount || 0;
}
dojo.lang.extend(dojo.animation.AnimationSequence, {
repeateCount: 0,
_anims: [],
_currAnim: -1,
onBegin: null,
onEnd: null,
onNext: null,
handler: null,
add: function() {
for(var i = 0; i < arguments.length; i++) {
this._anims.push(arguments[i]);
arguments[i]._animSequence = this;
}
},
remove: function(anim) {
for(var i = 0; i < this._anims.length; i++) {
if( this._anims[i] == anim ) {
this._anims[i]._animSequence = null;
this._anims.splice(i, 1);
break;
}
}
},
removeAll: function() {
for(var i = 0; i < this._anims.length; i++) {
this._anims[i]._animSequence = null;
}
this._anims = [];
this._currAnim = -1;
},
clear: function() {
this.removeAll();
},
play: function(gotoStart) {
if( this._anims.length == 0 ) { return; }
if( gotoStart || !this._anims[this._currAnim] ) {
this._currAnim = 0;
}
if( this._anims[this._currAnim] ) {
if( this._currAnim == 0 ) {
var e = {type: "begin", animation: this._anims[this._currAnim]};
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onBegin == "function") { this.onBegin(e); }
}
this._anims[this._currAnim].play(gotoStart);
}
},
pause: function() {
if( this._anims[this._currAnim] ) {
this._anims[this._currAnim].pause();
}
},
playPause: function() {
if( this._anims.length == 0 ) { return; }
if( this._currAnim == -1 ) { this._currAnim = 0; }
if( this._anims[this._currAnim] ) {
this._anims[this._currAnim].playPause();
}
},
stop: function() {
if( this._anims[this._currAnim] ) {
this._anims[this._currAnim].stop();
}
},
status: function() {
if( this._anims[this._currAnim] ) {
return this._anims[this._currAnim].status();
} else {
return "stopped";
}
},
_setCurrent: function(anim) {
for(var i = 0; i < this._anims.length; i++) {
if( this._anims[i] == anim ) {
this._currAnim = i;
break;
}
}
},
_playNext: function() {
if( this._currAnim == -1 || this._anims.length == 0 ) { return; }
this._currAnim++;
if( this._anims[this._currAnim] ) {
var e = {type: "next", animation: this._anims[this._currAnim]};
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onNext == "function") { this.onNext(e); }
this._anims[this._currAnim].play(true);
} else {
var e = {type: "end", animation: this._anims[this._anims.length-1]};
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onEnd == "function") { this.onEnd(e); }
if(this.repeatCount > 0) {
this._currAnim = 0;
this.repeatCount--;
this._anims[this._currAnim].play(true);
} else if(this.repeatCount == -1) {
this._currAnim = 0;
this._anims[this._currAnim].play(true);
} else {
this._currAnim = -1;
}
}
}
});

View file

@ -0,0 +1,39 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.Timer");
dojo.require("dojo.lang.func");
dojo.animation.Timer = function(intvl){
var timer = null;
this.isRunning = false;
this.interval = intvl;
this.onTick = function(){};
this.onStart = null;
this.onStop = null;
this.setInterval = function(ms){
if (this.isRunning) window.clearInterval(timer);
this.interval = ms;
if (this.isRunning) timer = window.setInterval(dojo.lang.hitch(this, "onTick"), this.interval);
};
this.start = function(){
if (typeof this.onStart == "function") this.onStart();
this.isRunning = true;
timer = window.setInterval(this.onTick, this.interval);
};
this.stop = function(){
if (typeof this.onStop == "function") this.onStop();
this.isRunning = false;
window.clearInterval(timer);
};
};

View file

@ -0,0 +1,18 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: [
"dojo.animation.AnimationEvent",
"dojo.animation.Animation",
"dojo.animation.AnimationSequence"
]
});
dojo.provide("dojo.animation.*");

248
webapp/web/src/behavior.js Normal file
View file

@ -0,0 +1,248 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.behavior");
dojo.require("dojo.event.*");
dojo.require("dojo.experimental");
dojo.experimental("dojo.behavior");
dojo.behavior = new function(){
function arrIn(obj, name){
if(!obj[name]){ obj[name] = []; }
return obj[name];
}
function forIn(obj, scope, func){
var tmpObj = {};
for(var x in obj){
if(typeof tmpObj[x] == "undefined"){
if(!func){
scope(obj[x], x);
}else{
func.call(scope, obj[x], x);
}
}
}
}
// FIXME: need a better test so we don't exclude nightly Safari's!
this.behaviors = {};
this.add = function(behaviorObj){
/* behavior objects are specified in the following format:
*
* {
* "#id": {
* "found": function(element){
* // ...
* },
*
* "onblah": {targetObj: foo, targetFunc: "bar"},
*
* "onblarg": "/foo/bar/baz/blarg",
*
* "onevent": function(evt){
* },
*
* "onotherevent: function(evt){
* // ...
* }
* },
*
* "#id2": {
* // ...
* },
*
* "#id3": function(element){
* // ...
* },
*
* // publish the match on a topic
* "#id4": "/found/topic/name",
*
* // match all direct descendants
* "#id4 > *": function(element){
* // ...
* },
*
* // match the first child node that's an element
* "#id4 > @firstElement": { ... },
*
* // match the last child node that's an element
* "#id4 > @lastElement": { ... },
*
* // all elements of type tagname
* "tagname": {
* // ...
* },
*
* // maps to roughly:
* // dojo.lang.forEach(body.getElementsByTagName("tagname1"), function(node){
* // dojo.lang.forEach(node.getElementsByTagName("tagname2"), function(node2){
* // dojo.lang.forEach(node2.getElementsByTagName("tagname3", function(node3){
* // // apply rules
* // });
* // });
* // });
* "tagname1 tagname2 tagname3": {
* // ...
* },
*
* ".classname": {
* // ...
* },
*
* "tagname.classname": {
* // ...
* },
* }
*
* The "found" method is a generalized handler that's called as soon
* as the node matches the selector. Rules for values that follow also
* apply to the "found" key.
*
* The "on*" handlers are attached with dojo.event.connect(). If the
* value is not a function but is rather an object, it's assumed to be
* the "other half" of a dojo.event.kwConnect() argument object. It
* may contain any/all properties of such a connection modifier save
* for the sourceObj and sourceFunc properties which are filled in by
* the system automatically. If a string is instead encountered, the
* node publishes the specified event on the topic contained in the
* string value.
*
* If the value corresponding to the ID key is a function and not a
* list, it's treated as though it was the value of "found".
*
*/
var tmpObj = {};
forIn(behaviorObj, this, function(behavior, name){
var tBehavior = arrIn(this.behaviors, name);
if((dojo.lang.isString(behavior))||(dojo.lang.isFunction(behavior))){
behavior = { found: behavior };
}
forIn(behavior, function(rule, ruleName){
arrIn(tBehavior, ruleName).push(rule);
});
});
}
this.apply = function(){
dojo.profile.start("dojo.behavior.apply");
var r = dojo.render.html;
// note, we apply one way for fast queries and one way for slow
// iteration. So be it.
var safariGoodEnough = (!r.safari);
if(r.safari){
// Anything over release #420 should work the fast way
var uas = r.UA.split("AppleWebKit/")[1];
if(parseInt(uas.match(/[0-9.]{3,}/)) >= 420){
safariGoodEnough = true;
}
}
if((dj_undef("behaviorFastParse", djConfig) ? (safariGoodEnough) : djConfig["behaviorFastParse"])){
this.applyFast();
}else{
this.applySlow();
}
dojo.profile.end("dojo.behavior.apply");
}
this.matchCache = {};
this.elementsById = function(id, handleRemoved){
var removed = [];
var added = [];
arrIn(this.matchCache, id);
if(handleRemoved){
var nodes = this.matchCache[id];
for(var x=0; x<nodes.length; x++){
if(nodes[x].id != ""){
removed.push(nodes[x]);
nodes.splice(x, 1);
x--;
}
}
}
var tElem = dojo.byId(id);
while(tElem){
if(!tElem["idcached"]){
added.push(tElem);
}
tElem.id = "";
tElem = dojo.byId(id);
}
this.matchCache[id] = this.matchCache[id].concat(added);
dojo.lang.forEach(this.matchCache[id], function(node){
node.id = id;
node.idcached = true;
});
return { "removed": removed, "added": added, "match": this.matchCache[id] };
}
this.applyToNode = function(node, action, ruleSetName){
if(typeof action == "string"){
dojo.event.topic.registerPublisher(action, node, ruleSetName);
}else if(typeof action == "function"){
if(ruleSetName == "found"){
action(node);
}else{
dojo.event.connect(node, ruleSetName, action);
}
}else{
action.srcObj = node;
action.srcFunc = ruleSetName;
dojo.event.kwConnect(action);
}
}
this.applyFast = function(){
dojo.profile.start("dojo.behavior.applyFast");
// fast DOM queries...wheeee!
forIn(this.behaviors, function(tBehavior, id){
var elems = dojo.behavior.elementsById(id);
dojo.lang.forEach(elems.added,
function(elem){
forIn(tBehavior, function(ruleSet, ruleSetName){
if(dojo.lang.isArray(ruleSet)){
dojo.lang.forEach(ruleSet, function(action){
dojo.behavior.applyToNode(elem, action, ruleSetName);
});
}
});
}
);
});
dojo.profile.end("dojo.behavior.applyFast");
}
this.applySlow = function(){
// iterate. Ugg.
dojo.profile.start("dojo.behavior.applySlow");
var all = document.getElementsByTagName("*");
var allLen = all.length;
for(var x=0; x<allLen; x++){
var elem = all[x];
if((elem.id)&&(!elem["behaviorAdded"])&&(this.behaviors[elem.id])){
elem["behaviorAdded"] = true;
forIn(this.behaviors[elem.id], function(ruleSet, ruleSetName){
if(dojo.lang.isArray(ruleSet)){
dojo.lang.forEach(ruleSet, function(action){
dojo.behavior.applyToNode(elem, action, ruleSetName);
});
}
});
}
}
dojo.profile.end("dojo.behavior.applySlow");
}
}
dojo.addOnLoad(dojo.behavior, "apply");

339
webapp/web/src/bootstrap1.js vendored Normal file
View file

@ -0,0 +1,339 @@
/**
* @file bootstrap1.js
*
* summary: First file that is loaded that 'bootstraps' the entire dojo library suite.
* note: Must run before hostenv_*.js file.
*
* @author Copyright 2004 Mark D. Anderson (mda@discerning.com)
* TODOC: should the copyright be changed to Dojo Foundation?
* @license Licensed under the Academic Free License 2.1 http://www.opensource.org/licenses/afl-2.1.php
*
* $Id: bootstrap1.js 4342 2006-06-11 23:03:30Z alex $
*/
// TODOC: HOW TO DOC THE BELOW?
// @global: djConfig
// summary:
// Application code can set the global 'djConfig' prior to loading
// the library to override certain global settings for how dojo works.
// description: The variables that can be set are as follows:
// - isDebug: false
// - allowQueryConfig: false
// - baseScriptUri: ""
// - baseRelativePath: ""
// - libraryScriptUri: ""
// - iePreventClobber: false
// - ieClobberMinimal: true
// - preventBackButtonFix: true
// - searchIds: []
// - parseWidgets: true
// TODOC: HOW TO DOC THESE VARIABLES?
// TODOC: IS THIS A COMPLETE LIST?
// note:
// 'djConfig' does not exist under 'dojo.*' so that it can be set before the
// 'dojo' variable exists.
// note:
// Setting any of these variables *after* the library has loaded does nothing at all.
// TODOC: is this still true? Release notes for 0.3 indicated they could be set after load.
//
//TODOC: HOW TO DOC THIS?
// @global: dj_global
// summary:
// an alias for the top-level global object in the host environment
// (e.g., the window object in a browser).
// description:
// Refer to 'dj_global' rather than referring to window to ensure your
// code runs correctly in contexts other than web browsers (eg: Rhino on a server).
var dj_global = this;
function dj_undef(/*String*/ name, /*Object?*/ object){
//summary: Returns true if 'name' is defined on 'object' (or globally if 'object' is null).
//description: Note that 'defined' and 'exists' are not the same concept.
if(object==null){ object = dj_global; }
// exception if object is not an Object
return (typeof object[name] == "undefined"); // Boolean
}
// make sure djConfig is defined
if(dj_undef("djConfig")){
var djConfig = {};
}
//TODOC: HOW TO DOC THIS?
// dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
if(dj_undef("dojo")){
var dojo = {};
}
//TODOC: HOW TO DOC THIS?
dojo.version = {
// summary: version number of this instance of dojo.
major: 0, minor: 3, patch: 1, flag: "",
revision: Number("$Rev: 4342 $".match(/[0-9]+/)[0]),
toString: function(){
with(dojo.version){
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
}
}
}
dojo.evalProp = function(/*String*/ name, /*Object*/ object, /*Boolean?*/ create){
// summary: Returns 'object[name]'. If not defined and 'create' is true, will return a new Object.
// description:
// Returns null if 'object[name]' is not defined and 'create' is not true.
// Note: 'defined' and 'exists' are not the same concept.
return (object && !dj_undef(name, object) ? object[name] : (create ? (object[name]={}) : undefined)); // mixed
}
dojo.parseObjPath = function(/*String*/ path, /*Object?*/ context, /*Boolean?*/ create){
// summary: Parse string path to an object, and return corresponding object reference and property name.
// description:
// Returns an object with two properties, 'obj' and 'prop'.
// 'obj[prop]' is the reference indicated by 'path'.
// path: Path to an object, in the form "A.B.C".
// context: Object to use as root of path. Defaults to 'dj_global'.
// create: If true, Objects will be created at any point along the 'path' that is undefined.
var object = (context != null ? context : dj_global);
var names = path.split('.');
var prop = names.pop();
for (var i=0,l=names.length;i<l && object;i++){
object = dojo.evalProp(names[i], object, create);
}
return {obj: object, prop: prop}; // Object: {obj: Object, prop: String}
}
dojo.evalObjPath = function(/*String*/ path, /*Boolean?*/ create){
// summary: Return the value of object at 'path' in the global scope, without using 'eval()'.
// path: Path to an object, in the form "A.B.C".
// create: If true, Objects will be created at any point along the 'path' that is undefined.
if(typeof path != "string"){
return dj_global;
}
// fast path for no periods
if(path.indexOf('.') == -1){
return dojo.evalProp(path, dj_global, create); // mixed
}
//MOW: old 'with' syntax was confusing and would throw an error if parseObjPath returned null.
var ref = dojo.parseObjPath(path, dj_global, create);
if(ref){
return dojo.evalProp(ref.prop, ref.obj, create); // mixed
}
return null;
}
// ****************************************************************
// global public utils
// TODOC: DO WE WANT TO NOTE THAT THESE ARE GLOBAL PUBLIC UTILS?
// ****************************************************************
dojo.errorToString = function(/*Error*/ exception){
// summary: Return an exception's 'message', 'description' or text.
// TODO: overriding Error.prototype.toString won't accomplish this?
// ... since natively generated Error objects do not always reflect such things?
if(!dj_undef("message", exception)){
return exception.message; // String
}else if(!dj_undef("description", exception)){
return exception.description; // String
}else{
return exception; // Error
}
}
dojo.raise = function(/*String*/ message, /*Error?*/ exception){
// summary: Throw an error message, appending text of 'exception' if provided.
// note: Also prints a message to the user using 'dojo.hostenv.println'.
if(exception){
message = message + ": "+dojo.errorToString(exception);
}
// print the message to the user if hostenv.println is defined
try { dojo.hostenv.println("FATAL: "+message); } catch (e) {}
throw Error(message);
}
//Stub functions so things don't break.
//TODOC: HOW TO DOC THESE?
dojo.debug = function(){}
dojo.debugShallow = function(obj){}
dojo.profile = { start: function(){}, end: function(){}, stop: function(){}, dump: function(){} };
function dj_eval(/*String*/ scriptFragment){
// summary: Perform an evaluation in the global scope. Use this rather than calling 'eval()' directly.
// description: Placed in a separate function to minimize size of trapped evaluation context.
// note:
// - JSC eval() takes an optional second argument which can be 'unsafe'.
// - Mozilla/SpiderMonkey eval() takes an optional second argument which is the
// scope object for new symbols.
return dj_global.eval ? dj_global.eval(scriptFragment) : eval(scriptFragment); // mixed
}
dojo.unimplemented = function(/*String*/ funcname, /*String?*/ extra){
// summary: Throw an exception because some function is not implemented.
// extra: Text to append to the exception message.
var message = "'" + funcname + "' not implemented";
if (extra != null) { message += " " + extra; }
dojo.raise(message);
}
dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
// summary: Log a debug message to indicate that a behavior has been deprecated.
// extra: Text to append to the message.
// removal: Text to indicate when in the future the behavior will be removed.
var message = "DEPRECATED: " + behaviour;
if(extra){ message += " " + extra; }
if(removal){ message += " -- will be removed in version: " + removal; }
dojo.debug(message);
}
dojo.inherits = function(/*Function*/ subclass, /*Function*/ superclass){
// summary: Set up inheritance between two classes.
if(typeof superclass != 'function'){
dojo.raise("dojo.inherits: superclass argument ["+superclass+"] must be a function (subclass: [" + subclass + "']");
}
subclass.prototype = new superclass();
subclass.prototype.constructor = subclass;
subclass.superclass = superclass.prototype;
// DEPRICATED: super is a reserved word, use 'superclass'
subclass['super'] = superclass.prototype;
}
dojo.render = (function(){
//TODOC: HOW TO DOC THIS?
// summary: Details rendering support, OS and browser of the current environment.
// TODOC: is this something many folks will interact with? If so, we should doc the structure created...
function vscaffold(prefs, names){
var tmp = {
capable: false,
support: {
builtin: false,
plugin: false
},
prefixes: prefs
};
for(var prop in names){
tmp[prop] = false;
}
return tmp;
}
return {
name: "",
ver: dojo.version,
os: { win: false, linux: false, osx: false },
html: vscaffold(["html"], ["ie", "opera", "khtml", "safari", "moz"]),
svg: vscaffold(["svg"], ["corel", "adobe", "batik"]),
vml: vscaffold(["vml"], ["ie"]),
swf: vscaffold(["Swf", "Flash", "Mm"], ["mm"]),
swt: vscaffold(["Swt"], ["ibm"])
};
})();
// ****************************************************************
// dojo.hostenv methods that must be defined in hostenv_*.js
// ****************************************************************
/**
* The interface definining the interaction with the EcmaScript host environment.
*/
/*
* None of these methods should ever be called directly by library users.
* Instead public methods such as loadModule should be called instead.
*/
dojo.hostenv = (function(){
// TODOC: HOW TO DOC THIS?
// summary: Provides encapsulation of behavior that changes across different 'host environments'
// (different browsers, server via Rhino, etc).
// description: None of these methods should ever be called directly by library users.
// Use public methods such as 'loadModule' instead.
// default configuration options
var config = {
isDebug: false,
allowQueryConfig: false,
baseScriptUri: "",
baseRelativePath: "",
libraryScriptUri: "",
iePreventClobber: false,
ieClobberMinimal: true,
preventBackButtonFix: true,
searchIds: [],
parseWidgets: true
};
if (typeof djConfig == "undefined") { djConfig = config; }
else {
for (var option in config) {
if (typeof djConfig[option] == "undefined") {
djConfig[option] = config[option];
}
}
}
return {
name_: '(unset)',
version_: '(unset)',
getName: function(){
// sumary: Return the name of the host environment.
return this.name_; // String
},
getVersion: function(){
// summary: Return the version of the hostenv.
return this.version_; // String
},
getText: function(/*String*/ uri){
// summary: Read the plain/text contents at the specified 'uri'.
// description:
// If 'getText()' is not implemented, then it is necessary to override
// 'loadUri()' with an implementation that doesn't rely on it.
dojo.unimplemented('getText', "uri=" + uri);
}
};
})();
dojo.hostenv.getBaseScriptUri = function(){
// summary: Return the base script uri that other scripts are found relative to.
// TODOC: HUH? This comment means nothing to me. What other scripts? Is this the path to other dojo libraries?
// MAYBE: Return the base uri to scripts in the dojo library. ???
// return: Empty string or a path ending in '/'.
if(djConfig.baseScriptUri.length){
return djConfig.baseScriptUri;
}
// MOW: Why not:
// uri = djConfig.libraryScriptUri || djConfig.baseRelativePath
// ??? Why 'new String(...)'
var uri = new String(djConfig.libraryScriptUri||djConfig.baseRelativePath);
if (!uri) { dojo.raise("Nothing returned by getLibraryScriptUri(): " + uri); }
// MOW: uri seems to not be actually used. Seems to be hard-coding to djConfig.baseRelativePath... ???
var lastslash = uri.lastIndexOf('/'); // MOW ???
djConfig.baseScriptUri = djConfig.baseRelativePath;
return djConfig.baseScriptUri; // String
}

174
webapp/web/src/bootstrap2.js vendored Normal file
View file

@ -0,0 +1,174 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
//Semicolon is for when this file is integrated with a custom build on one line
//with some other file's contents. Sometimes that makes things not get defined
//properly, particularly with the using the closure below to do all the work.
;(function(){
//Don't do this work if dojo.js has already done it.
if(typeof dj_usingBootstrap != "undefined"){
return;
}
var isRhino = false;
var isSpidermonkey = false;
var isDashboard = false;
if((typeof this["load"] == "function")&&((typeof this["Packages"] == "function")||(typeof this["Packages"] == "object"))){
isRhino = true;
}else if(typeof this["load"] == "function"){
isSpidermonkey = true;
}else if(window.widget){
isDashboard = true;
}
var tmps = [];
if((this["djConfig"])&&((djConfig["isDebug"])||(djConfig["debugAtAllCosts"]))){
tmps.push("debug.js");
}
if((this["djConfig"])&&(djConfig["debugAtAllCosts"])&&(!isRhino)&&(!isDashboard)){
tmps.push("browser_debug.js");
}
//Support compatibility packages. Right now this only allows setting one
//compatibility package. Might need to revisit later down the line to support
//more than one.
if((this["djConfig"])&&(djConfig["compat"])){
tmps.push("compat/" + djConfig["compat"] + ".js");
}
var loaderRoot = djConfig["baseScriptUri"];
if((this["djConfig"])&&(djConfig["baseLoaderUri"])){
loaderRoot = djConfig["baseLoaderUri"];
}
for(var x=0; x < tmps.length; x++){
var spath = loaderRoot+"src/"+tmps[x];
if(isRhino||isSpidermonkey){
load(spath);
} else {
try {
document.write("<scr"+"ipt type='text/javascript' src='"+spath+"'></scr"+"ipt>");
} catch (e) {
var script = document.createElement("script");
script.src = spath;
document.getElementsByTagName("head")[0].appendChild(script);
}
}
}
})();
// Localization routines
/**
* The locale to look for string bundles if none are defined for your locale. Translations for all strings
* should be provided in this locale.
*/
//TODO: this really belongs in translation metadata, not in code
dojo.fallback_locale = 'en';
/**
* Returns canonical form of locale, as used by Dojo. All variants are case-insensitive and are separated by '-'
* as specified in RFC 3066
*/
dojo.normalizeLocale = function(locale) {
return locale ? locale.toLowerCase() : dojo.locale;
};
/**
* requireLocalization() is for loading translated bundles provided within a package in the namespace.
* Contents are typically strings, but may be any name/value pair, represented in JSON format.
* A bundle is structured in a program as follows:
*
* <package>/
* nls/
* de/
* mybundle.js
* de-at/
* mybundle.js
* en/
* mybundle.js
* en-us/
* mybundle.js
* en-gb/
* mybundle.js
* es/
* mybundle.js
* ...etc
*
* where package is part of the namespace as used by dojo.require(). Each directory is named for a
* locale as specified by RFC 3066, (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
*
* For a given locale, string bundles will be loaded for that locale and all general locales above it, as well
* as a system-specified fallback. For example, "de_at" will also load "de" and "en". Lookups will traverse
* the locales in this order. A build step can preload the bundles to avoid data redundancy and extra network hits.
*
* @param modulename package in which the bundle is found
* @param bundlename bundle name, typically the filename without the '.js' suffix
* @param locale the locale to load (optional) By default, the browser's user locale as defined
* in dojo.locale
*/
dojo.requireLocalization = function(modulename, bundlename, locale /*optional*/){
dojo.debug("EXPERIMENTAL: dojo.requireLocalization"); //dojo.experimental
var syms = dojo.hostenv.getModuleSymbols(modulename);
var modpath = syms.concat("nls").join("/");
locale = dojo.normalizeLocale(locale);
var elements = locale.split('-');
var searchlist = [];
for(var i = elements.length; i > 0; i--){
searchlist.push(elements.slice(0, i).join('-'));
}
if(searchlist[searchlist.length-1] != dojo.fallback_locale){
searchlist.push(dojo.fallback_locale);
}
var bundlepackage = [modulename, "_nls", bundlename].join(".");
var bundle = dojo.hostenv.startPackage(bundlepackage);
dojo.hostenv.loaded_modules_[bundlepackage] = bundle;
var inherit = false;
for(var i = searchlist.length - 1; i >= 0; i--){
var loc = searchlist[i];
var pkg = [bundlepackage, loc].join(".");
var loaded = false;
if(!dojo.hostenv.findModule(pkg)){
// Mark loaded whether it's found or not, so that further load attempts will not be made
dojo.hostenv.loaded_modules_[pkg] = null;
var filespec = [modpath, loc, bundlename].join("/") + '.js';
loaded = dojo.hostenv.loadPath(filespec, null, function(hash) {
bundle[loc] = hash;
if(inherit){
// Use mixins approach to copy string references from inherit bundle, but skip overrides.
for(var x in inherit){
if(!bundle[loc][x]){
bundle[loc][x] = inherit[x];
}
}
}
/*
// Use prototype to point to other bundle, then copy in result from loadPath
bundle[loc] = new function(){};
if(inherit){ bundle[loc].prototype = inherit; }
for(var i in hash){ bundle[loc][i] = hash[i]; }
*/
});
}else{
loaded = true;
}
if(loaded && bundle[loc]){
inherit = bundle[loc];
}
}
};

View file

@ -0,0 +1,162 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.hostenv.loadedUris.push("../src/bootstrap1.js");
dojo.hostenv.loadedUris.push("../src/loader.js");
dojo.hostenv.loadedUris.push("../src/hostenv_browser.js");
dojo.hostenv.loadedUris.push("../src/bootstrap2.js");
function removeComments(contents){
contents = new String((!contents) ? "" : contents);
// clobber all comments
contents = contents.replace( /^(.*?)\/\/(.*)$/mg , "$1");
contents = contents.replace( /(\n)/mg , "__DOJONEWLINE");
contents = contents.replace( /\/\*(.*?)\*\//g , "");
return contents.replace( /__DOJONEWLINE/mg , "\n");
}
dojo.hostenv.getRequiresAndProvides = function(contents){
// FIXME: should probably memoize this!
if(!contents){ return []; }
// check to see if we need to load anything else first. Ugg.
var deps = [];
var tmp;
RegExp.lastIndex = 0;
var testExp = /dojo.(hostenv.loadModule|hosetnv.require|require|requireIf|kwCompoundRequire|hostenv.conditionalLoadModule|hostenv.startPackage|provide)\([\w\W]*?\)/mg;
while((tmp = testExp.exec(contents)) != null){
deps.push(tmp[0]);
}
return deps;
}
dojo.hostenv.getDelayRequiresAndProvides = function(contents){
// FIXME: should probably memoize this!
if(!contents){ return []; }
// check to see if we need to load anything else first. Ugg.
var deps = [];
var tmp;
RegExp.lastIndex = 0;
var testExp = /dojo.(requireAfterIf)\([\w\W]*?\)/mg;
while((tmp = testExp.exec(contents)) != null){
deps.push(tmp[0]);
}
return deps;
}
/*
dojo.getNonExistantDescendants = function(objpath){
var ret = [];
// fast path for no periods
if(typeof objpath != "string"){ return dj_global; }
if(objpath.indexOf('.') == -1){
if(dj_undef(objpath, dj_global)){
ret.push[objpath];
}
return ret;
}
var syms = objpath.split(/\./);
var obj = dj_global;
for(var i=0;i<syms.length;++i){
if(dj_undef(syms[i], obj)){
for(var j=i; j<syms.length; j++){
ret.push(syms.slice(0, j+1).join("."));
}
break;
}
}
return ret;
}
*/
dojo.clobberLastObject = function(objpath){
if(objpath.indexOf('.') == -1){
if(!dj_undef(objpath, dj_global)){
delete dj_global[objpath];
}
return true;
}
var syms = objpath.split(/\./);
var base = dojo.evalObjPath(syms.slice(0, -1).join("."), false);
var child = syms[syms.length-1];
if(!dj_undef(child, base)){
// alert(objpath);
delete base[child];
return true;
}
return false;
}
var removals = [];
function zip(arr){
var ret = [];
var seen = {};
for(var x=0; x<arr.length; x++){
if(!seen[arr[x]]){
ret.push(arr[x]);
seen[arr[x]] = true;
}
}
return ret;
}
// over-write dj_eval to prevent actual loading of subsequent files
var old_dj_eval = dj_eval;
dj_eval = function(){ return true; }
dojo.hostenv.oldLoadUri = dojo.hostenv.loadUri;
dojo.hostenv.loadUri = function(uri){
if(dojo.hostenv.loadedUris[uri]){
return true; // fixes endless recursion opera trac 471
}
try{
var text = this.getText(uri, null, true);
var requires = dojo.hostenv.getRequiresAndProvides(text);
eval(requires.join(";"));
dojo.hostenv.loadedUris.push(uri);
dojo.hostenv.loadedUris[uri] = true;
var delayRequires = dojo.hostenv.getDelayRequiresAndProvides(text);
eval(delayRequires.join(";"));
}catch(e){
alert(e);
}
return true;
}
dojo.hostenv.writeIncludes = function(){
for(var x=removals.length-1; x>=0; x--){
dojo.clobberLastObject(removals[x]);
}
var depList = [];
var seen = {};
for(var x=0; x<dojo.hostenv.loadedUris.length; x++){
var curi = dojo.hostenv.loadedUris[x];
// dojo.debug(curi);
if(!seen[curi]){
seen[curi] = true;
depList.push(curi);
}
}
dojo.hostenv._global_omit_module_check = true;
for(var x=4; x<depList.length; x++){
document.write("<script type='text/javascript' src='"+depList[x]+"'></script>");
}
document.write("<script type='text/javascript'>dojo.hostenv._global_omit_module_check = false;</script>");
// turn off debugAtAllCosts, so that dojo.require() calls inside of ContentPane hrefs
// work correctly
dj_eval = old_dj_eval;
dojo.hostenv.loadUri = dojo.hostenv.oldLoadUri;
}

View file

@ -0,0 +1,146 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.ArrayList");
dojo.require("dojo.collections.Collections");
dojo.collections.ArrayList=function(/* array? */arr){
// summary
// Returns a new object of type dojo.collections.ArrayList
var items=[];
if(arr) items=items.concat(arr);
this.count=items.length;
this.add=function(/* object */obj){
// summary
// Add an element to the collection.
items.push(obj);
this.count=items.length;
};
this.addRange=function(/* array */a){
// summary
// Add a range of objects to the ArrayList
if(a.getIterator){
var e=a.getIterator();
while(!e.atEnd()){
this.add(e.get());
}
this.count=items.length;
}else{
for(var i=0; i<a.length; i++){
items.push(a[i]);
}
this.count=items.length;
}
};
this.clear=function(){
// summary
// Clear all elements out of the collection, and reset the count.
items.splice(0, items.length);
this.count=0;
};
this.clone=function(){
// summary
// Clone the array list
return new dojo.collections.ArrayList(items); // dojo.collections.ArrayList
};
this.contains=function(/* object */obj){
// summary
// Check to see if the passed object is a member in the ArrayList
for(var i=0; i < items.length; i++){
if(items[i] == obj) {
return true; // bool
}
}
return false; // bool
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(items, fn, s);
}else{
for(var i=0; i<items.length; i++){
fn.call(s, items[i], i, items);
}
}
};
this.getIterator=function(){
// summary
// Get an Iterator for this object
return new dojo.collections.Iterator(items); // dojo.collections.Iterator
};
this.indexOf=function(/* object */obj){
// summary
// Return the numeric index of the passed object; will return -1 if not found.
for(var i=0; i < items.length; i++){
if(items[i] == obj) {
return i; // int
}
}
return -1; // int
};
this.insert=function(/* int */ i, /* object */ obj){
// summary
// Insert the passed object at index i
items.splice(i,0,obj);
this.count=items.length;
};
this.item=function(/* int */ i){
// summary
// return the element at index i
return items[i]; // object
};
this.remove=function(/* object */obj){
// summary
// Look for the passed object, and if found, remove it from the internal array.
var i=this.indexOf(obj);
if(i >=0) {
items.splice(i,1);
}
this.count=items.length;
};
this.removeAt=function(/* int */ i){
// summary
// return an array with function applied to all elements
items.splice(i,1);
this.count=items.length;
};
this.reverse=function(){
// summary
// Reverse the internal array
items.reverse();
};
this.sort=function(/* function? */ fn){
// summary
// sort the internal array
if(fn){
items.sort(fn);
}else{
items.sort();
}
};
this.setByIndex=function(/* int */ i, /* object */ obj){
// summary
// Set an element in the array by the passed index.
items[i]=obj;
this.count=items.length;
};
this.toArray=function(){
// summary
// Return a new array with all of the items of the internal array concatenated.
return [].concat(items);
}
this.toString=function(/* string */ delim){
// summary
// implementation of toString, follows [].toString();
return items.join((delim||","));
};
};

View file

@ -0,0 +1,203 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.BinaryTree");
dojo.require("dojo.collections.Collections");
dojo.require("dojo.experimental");
dojo.experimental("dojo.collections.BinaryTree");
dojo.collections.BinaryTree=function(data){
function node(data, rnode, lnode){
this.value=data||null;
this.right=rnode||null;
this.left=lnode||null;
this.clone=function(){
var c=new node();
if (this.value.value) c.value=this.value.clone();
else c.value=this.value;
if (this.left) c.left=this.left.clone();
if (this.right) c.right=this.right.clone();
}
this.compare=function(n){
if (this.value > n.value) return 1;
if (this.value < n.value) return -1;
return 0;
}
this.compareData=function(d){
if (this.value > d) return 1;
if (this.value < d) return -1;
return 0;
}
}
function inorderTraversalBuildup(current, a){
if (current){
inorderTraversalBuildup(current.left, a);
a.add(current);
inorderTraversalBuildup(current.right, a);
}
}
function preorderTraversal(current, sep){
var s="";
if (current){
s=current.value.toString() + sep;
s += preorderTraversal(current.left, sep);
s += preorderTraversal(current.right, sep);
}
return s;
}
function inorderTraversal(current, sep){
var s="";
if (current){
s=inorderTraversal(current.left, sep);
s += current.value.toString() + sep;
s += inorderTraversal(current.right, sep);
}
return s;
}
function postorderTraversal(current, sep){
var s="";
if (current){
s=postorderTraversal(current.left, sep);
s += postorderTraversal(current.right, sep);
s += current.value.toString() + sep;
}
return s;
}
function searchHelper(current, data){
if (!current) return null;
var i=current.compareData(data);
if (i==0) return current;
if (i>0) return searchHelper(current.left, data);
else return searchHelper(current.right, data);
}
this.add=function(data){
var n=new node(data);
var i;
var current=root;
var parent=null;
while (current){
i=current.compare(n);
if (i == 0) return;
parent=current;
if (i > 0) current=current.left;
else current=current.right;
}
this.count++;
if (!parent) root=n;
else {
i=parent.compare(n);
if (i > 0) parent.left=n;
else parent.right=n;
}
};
this.clear=function(){
root=null;
this.count=0;
};
this.clone=function(){
var c=new dojo.collections.BinaryTree();
c.root=root.clone();
c.count=this.count;
return c;
};
this.contains=function(data){
return this.search(data) != null;
};
this.deleteData=function(data){
var current=root;
var parent=null;
var i=current.compareData(data);
while (i != 0 && current != null){
if (i > 0){
parent=current;
current=current.left;
} else if (i < 0) {
parent=current;
current=current.right;
}
i=current.compareData(data);
}
if (!current) return;
this.count--;
if (!current.right) {
if (!parent) root=current.left;
else {
i=parent.compare(current);
if (i > 0) parent.left=current.left;
else if (i < 0) parent.right=current.left;
}
} else if (!current.right.left){
if (!parent) root=current.right;
else {
i=parent.compare(current);
if (i > 0) parent.left=current.right;
else if (i < 0) parent.right=current.right;
}
} else {
var leftmost=current.right.left;
var lmParent=current.right;
while (leftmost.left != null){
lmParent=leftmost;
leftmost=leftmost.left;
}
lmParent.left=leftmost.right;
leftmost.left=current.left;
leftmost.right=current.right;
if (!parent) root=leftmost;
else {
i=parent.compare(current);
if (i > 0) parent.left=leftmost;
else if (i < 0) parent.right=leftmost;
}
}
};
this.getIterator=function(){
var a=[];
inorderTraversalBuildup(root, a);
return new dojo.collections.Iterator(a);
};
this.search=function(data){
return searchHelper(root, data);
};
this.toString=function(order, sep){
if (!order) var order=dojo.collections.BinaryTree.TraversalMethods.Inorder;
if (!sep) var sep=" ";
var s="";
switch (order){
case dojo.collections.BinaryTree.TraversalMethods.Preorder:
s=preorderTraversal(root, sep);
break;
case dojo.collections.BinaryTree.TraversalMethods.Inorder:
s=inorderTraversal(root, sep);
break;
case dojo.collections.BinaryTree.TraversalMethods.Postorder:
s=postorderTraversal(root, sep);
break;
};
if (s.length == 0) return "";
else return s.substring(0, s.length - sep.length);
};
this.count=0;
var root=this.root=null;
if (data) {
this.add(data);
}
}
dojo.collections.BinaryTree.TraversalMethods={
Preorder : 0,
Inorder : 1,
Postorder : 2
};

View file

@ -0,0 +1,125 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Collections");
dojo.collections={Collections:true};
dojo.collections.DictionaryEntry=function(/* string */k, /* object */v){
// summary
// return an object of type dojo.collections.DictionaryEntry
this.key=k;
this.value=v;
this.valueOf=function(){
return this.value; // object
};
this.toString=function(){
return String(this.value); // string
};
}
/* Iterators
* The collections.Iterators (Iterator and DictionaryIterator) are built to
* work with the Collections included in this namespace. However, they *can*
* be used with arrays and objects, respectively, should one choose to do so.
*/
dojo.collections.Iterator=function(/* array */arr){
// summary
// return an object of type dojo.collections.Iterator
var a=arr;
var position=0;
this.element=a[position]||null;
this.atEnd=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
return (position>=a.length); // bool
};
this.get=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
if(this.atEnd()){
return null; // object
}
this.element=a[position++];
return this.element; // object
};
this.map=function(/* function */fn, /* object? */scope){
// summary
// Functional iteration with optional scope.
var s=scope||dj_global;
if(Array.map){
return Array.map(a,fn,s); // array
}else{
var arr=[];
for(var i=0; i<a.length; i++){
arr.push(fn.call(s,a[i]));
}
return arr; // array
}
};
this.reset=function(){
// summary
// reset the internal cursor.
position=0;
this.element=a[position];
};
}
/* Notes:
* The DictionaryIterator no longer supports a key and value property;
* the reality is that you can use this to iterate over a JS object
* being used as a hashtable.
*/
dojo.collections.DictionaryIterator=function(/* object */obj){
// summary
// return an object of type dojo.collections.DictionaryIterator
var a=[]; // Create an indexing array
var testObject={};
for(var p in obj){
if(!testObject[p]){
a.push(obj[p]); // fill it up
}
}
var position=0;
this.element=a[position]||null;
this.atEnd=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
return (position>=a.length); // bool
};
this.get=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
if(this.atEnd()){
return null; // object
}
this.element=a[position++];
return this.element; // object
};
this.map=function(/* function */fn, /* object? */scope){
// summary
// Functional iteration with optional scope.
var s=scope||dj_global;
if(Array.map){
return Array.map(a,fn,s); // array
}else{
var arr=[];
for(var i=0; i<a.length; i++){
arr.push(fn.call(s,a[i]));
}
return arr; // array
}
};
this.reset=function() {
// summary
// reset the internal cursor.
position=0;
this.element=a[position];
};
};

View file

@ -0,0 +1,129 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Dictionary");
dojo.require("dojo.collections.Collections");
dojo.collections.Dictionary=function(/* dojo.collections.Dictionary? */dictionary){
// summary
// Returns an object of type dojo.collections.Dictionary
var items={};
this.count=0;
// comparator for property addition and access.
var testObject={};
this.add=function(/* string */k, /* object */v){
// summary
// Add a new item to the Dictionary.
var b=(k in items);
items[k]=new dojo.collections.DictionaryEntry(k,v);
if(!b){
this.count++;
}
};
this.clear=function(){
// summary
// Clears the internal dictionary.
items={};
this.count=0;
};
this.clone=function(){
// summary
// Returns a new instance of dojo.collections.Dictionary; note the the dictionary is a clone but items might not be.
return new dojo.collections.Dictionary(this); // dojo.collections.Dictionary
};
this.contains=this.containsKey=function(/* string */k){
// summary
// Check to see if the dictionary has an entry at key "k".
if(testObject[k]){
return false; // bool
}
return (items[k]!=null); // bool
};
this.containsValue=function(/* object */v){
// summary
// Check to see if the dictionary has an entry with value "v".
var e=this.getIterator();
while(e.get()){
if(e.element.value==v){
return true; // bool
}
}
return false; // bool
};
this.entry=function(/* string */k){
// summary
// Accessor method; similar to dojo.collections.Dictionary.item but returns the actual Entry object.
return items[k]; // dojo.collections.DictionaryEntry
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var a=[]; // Create an indexing array
for(var p in items) {
if(!testObject[p]){
a.push(items[p]); // fill it up
}
}
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(a, fn, s);
}else{
for(var i=0; i<a.length; i++){
fn.call(s, a[i], i, a);
}
}
};
this.getKeyList=function(){
// summary
// Returns an array of the keys in the dictionary.
return (this.getIterator()).map(function(entry){
return entry.key;
}); // array
};
this.getValueList=function(){
// summary
// Returns an array of the values in the dictionary.
return (this.getIterator()).map(function(entry){
return entry.value;
}); // array
};
this.item=function(/* string */k){
// summary
// Accessor method.
if(k in items){
return items[k].valueOf(); // object
}
return undefined; // object
};
this.getIterator=function(){
// summary
// Gets a dojo.collections.DictionaryIterator for iteration purposes.
return new dojo.collections.DictionaryIterator(items); // dojo.collections.DictionaryIterator
};
this.remove=function(/* string */k){
// summary
// Removes the item at k from the internal collection.
if(k in items && !testObject[k]){
delete items[k];
this.count--;
return true; // bool
}
return false; // bool
};
if (dictionary){
var e=dictionary.getIterator();
while(e.get()) {
this.add(e.element.key, e.element.value);
}
}
};

View file

@ -0,0 +1,153 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Graph");
dojo.require("dojo.collections.Collections");
dojo.experimental("dojo.collections.Graph");
dojo.collections.Graph=function(nodes){
function node(key, data, neighbors) {
this.key=key;
this.data=data;
this.neighbors=neighbors||new adjacencyList();
this.addDirected=function(){
if (arguments[0].constructor==edgeToNeighbor){
this.neighbors.add(arguments[0]);
}else{
var n=arguments[0];
var cost=arguments[1]||0;
this.neighbors.add(new edgeToNeighbor(n, cost));
}
}
}
function nodeList(){
var d=new dojo.collections.Dictionary();
function nodelistiterator(){
var o=[] ; // Create an indexing array
var e=d.getIterator();
while(e.get()){
o[o.length]=e.element;
}
var position=0;
this.element=o[position]||null;
this.atEnd=function(){
return (position>=o.length);
}
this.get=function(){
if(this.atEnd()){
return null; // object
}
this.element=o[position++];
return this.element; // object
};
this.map=function(/* function */fn, /* object? */scope){
var s=scope||dj_global;
if(Array.map){
return Array.map(o,fn,s); // array
}else{
var arr=[];
for(var i=0; i<o.length; i++){
arr.push(fn.call(s,o[i]));
}
return arr; // array
}
};
this.reset=function(){
position=0;
this.element=o[position];
};
}
this.add=function(node){
d.add(node.key, node);
};
this.clear=function(){
d.clear();
};
this.containsKey=function(key){
return d.containsKey(key);
};
this.getIterator=function(){
return new nodelistiterator(this);
};
this.item=function(key){
return d.item(key);
};
this.remove=function(node){
d.remove(node.key);
};
}
function edgeToNeighbor(node, cost){
this.neighbor=node;
this.cost=cost;
}
function adjacencyList(){
var d=[];
this.add=function(o){
d.push(o);
};
this.item=function(i){
return d[i];
};
this.getIterator=function(){
return new dojo.collections.Iterator([].concat(d));
};
}
this.nodes=nodes||new nodeList();
this.count=this.nodes.count;
this.clear=function(){
this.nodes.clear();
this.count=0;
};
this.addNode=function(){
var n=arguments[0];
if(arguments.length > 1){
n=new node(arguments[0],arguments[1]);
}
if(!this.nodes.containsKey(n.key)){
this.nodes.add(n);
this.count++;
}
};
this.addDirectedEdge=function(uKey, vKey, cost){
var uNode,vNode;
if(uKey.constructor!= node){
uNode=this.nodes.item(uKey);
vNode=this.nodes.item(vKey);
}else{
uNode=uKey;
vNode=vKey;
}
var c=cost||0;
uNode.addDirected(vNode,c);
};
this.addUndirectedEdge=function(uKey, vKey, cost){
var uNode, vNode;
if(uKey.constructor!=node){
uNode=this.nodes.item(uKey);
vNode=this.nodes.item(vKey);
}else{
uNode=uKey;
vNode=vKey;
}
var c=cost||0;
uNode.addDirected(vNode,c);
vNode.addDirected(uNode,c);
};
this.contains=function(n){
return this.nodes.containsKey(n.key);
};
this.containsKey=function(k){
return this.nodes.containsKey(k);
};
}

View file

@ -0,0 +1,87 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Queue");
dojo.require("dojo.collections.Collections");
dojo.collections.Queue=function(/* array? */arr){
// summary
// return an object of type dojo.collections.Queue
var q=[];
if (arr){
q=q.concat(arr);
}
this.count=q.length;
this.clear=function(){
// summary
// clears the internal collection
q=[];
this.count=q.length;
};
this.clone=function(){
// summary
// creates a new Queue based on this one
return new dojo.collections.Queue(q); // dojo.collections.Queue
};
this.contains=function(/* object */ o){
// summary
// Check to see if the passed object is an element in this queue
for(var i=0; i<q.length; i++){
if (q[i]==o){
return true; // bool
}
}
return false; // bool
};
this.copyTo=function(/* array */ arr, /* int */ i){
// summary
// Copy the contents of this queue into the passed array at index i.
arr.splice(i,0,q);
};
this.dequeue=function(){
// summary
// shift the first element off the queue and return it
var r=q.shift();
this.count=q.length;
return r; // object
};
this.enqueue=function(/* object */ o){
// summary
// put the passed object at the end of the queue
this.count=q.push(o);
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(q, fn, s);
}else{
for(var i=0; i<q.length; i++){
fn.call(s, q[i], i, q);
}
}
};
this.getIterator=function(){
// summary
// get an Iterator based on this queue.
return new dojo.collections.Iterator(q); // dojo.collections.Iterator
};
this.peek=function(){
// summary
// get the next element in the queue without altering the queue.
return q[0];
};
this.toArray=function(){
// summary
// return an array based on the internal array of the queue.
return [].concat(q);
};
};

View file

@ -0,0 +1,84 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Set");
dojo.require("dojo.collections.Collections");
dojo.require("dojo.collections.ArrayList");
// straight up sets are based on arrays or array-based collections.
dojo.collections.Set = new function(){
this.union = function(setA, setB){
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var result = new dojo.collections.ArrayList(setA.toArray());
var e = setB.getIterator();
while(!e.atEnd()){
var item=e.get();
if(!result.contains(item)){
result.add(item);
}
}
return result;
};
this.intersection = function(setA, setB){
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var result = new dojo.collections.ArrayList();
var e = setB.getIterator();
while(!e.atEnd()){
var item=e.get();
if(setA.contains(item)){
result.add(item);
}
}
return result;
};
// returns everything in setA that is not in setB.
this.difference = function(setA, setB){
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var result = new dojo.collections.ArrayList();
var e=setA.getIterator();
while(!e.atEnd()){
var item=e.get();
if(!setB.contains(item)){
result.add(item);
}
}
return result;
};
this.isSubSet = function(setA, setB) {
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var e = setA.getIterator();
while(!e.atEnd()){
if(!setB.contains(e.get())){
return false;
}
}
return true;
};
this.isSuperSet = function(setA, setB){
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var e = setB.getIterator();
while(!e.atEnd()){
if(!setA.contains(e.get())){
return false;
}
}
return true;
};
}();

View file

@ -0,0 +1,146 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.SkipList");
dojo.require("dojo.collections.Collections");
dojo.require("dojo.experimental");
dojo.experimental("dojo.collections.SkipList");
dojo.collections.SkipList = function(){
function node(height, val){
this.value = val;
this.height = height;
this.nodes = new nodeList(height);
this.compare = function(val){
if (this.value > val) return 1;
if (this.value < val) return -1;
return 0;
}
this.incrementHeight = function(){
this.nodes.incrementHeight();
this.height++;
};
this.decrementHeight = function(){
this.nodes.decrementHeight();
this.height--;
};
}
function nodeList(height){
var arr = [];
this.height = height;
for (var i = 0; i < height; i++) arr[i] = null;
this.item = function(i){
return arr[i];
};
this.incrementHeight = function(){
this.height++;
arr[this.height] = null;
};
this.decrementHeight = function(){
arr.splice(arr.length - 1, 1);
this.height--;
};
}
function iterator(list){
this.current = list.head;
this.atEnd = false;
this.moveNext = function(){
if (this.atEnd) return !this.atEnd;
this.current = this.current.nodes[0];
this.atEnd = (this.current == null);
return !this.atEnd;
};
this.reset = function(){
this.current = null;
};
}
function chooseRandomHeight(max){
var level = 1;
while (Math.random() < PROB && level < max) level++;
return level;
}
var PROB = 0.5;
var comparisons = 0;
this.head = new node(1);
this.count = 0;
this.add = function(val){
var updates = [];
var current = this.head;
for (var i = this.head.height; i >= 0; i--){
if (!(current.nodes[i] != null && current.nodes[i].compare(val) < 0)) comparisons++;
while (current.nodes[i] != null && current.nodes[i].compare(val) < 0){
current = current.nodes[i];
comparisons++;
}
updates[i] = current;
}
if (current.nodes[0] != null && current.nodes[0].compare(val) == 0) return;
var n = new node(val, chooseRandomHeight(this.head.height + 1));
this.count++;
if (n.height > this.head.height){
this.head.incrementHeight();
this.head.nodes[this.head.height - 1] = n;
}
for (i = 0; i < n.height; i++){
if (i < updates.length) {
n.nodes[i] = updates[i].nodes[i];
updates[i].nodes[i] = n;
}
}
};
this.contains = function(val){
var current = this.head;
var i;
for (i = this.head.height - 1; i >= 0; i--) {
while (current.item(i) != null) {
comparisons++;
var result = current.nodes[i].compare(val);
if (result == 0) return true;
else if (result < 0) current = current.nodes[i];
else break;
}
}
return false;
};
this.getIterator = function(){
return new iterator(this);
};
this.remove = function(val){
var updates = [];
var current = this.head;
for (var i = this.head.height - 1; i >= 0; i--){
if (!(current.nodes[i] != null && current.nodes[i].compare(val) < 0)) comparisons++;
while (current.nodes[i] != null && current.nodes[i].compare(val) < 0) {
current = current.nodes[i];
comparisons++;
}
updates[i] = current;
}
current = current.nodes[0];
if (current != null && current.compare(val) == 0){
this.count--;
for (var i = 0; i < this.head.height; i++){
if (updates[i].nodes[i] != current) break;
else updates[i].nodes[i] = current.nodes[i];
}
if (this.head.nodes[this.head.height - 1] == null) this.head.decrementHeight();
}
};
this.resetComparisons = function(){
comparisons = 0;
};
}

View file

@ -0,0 +1,211 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.SortedList");
dojo.require("dojo.collections.Collections");
dojo.collections.SortedList=function(/* object? */ dictionary){
// summary
// creates a collection that acts like a dictionary but is also internally sorted.
// Note that the act of adding any elements forces an internal resort, making this object potentially slow.
var _this=this;
var items={};
var q=[];
var sorter=function(a,b){
if (a.key > b.key) return 1;
if (a.key < b.key) return -1;
return 0;
};
var build=function(){
q=[];
var e=_this.getIterator();
while (!e.atEnd()){
q.push(e.get());
}
q.sort(sorter);
};
var testObject={};
this.count=q.length;
this.add=function(/* string */ k,/* object */v){
// summary
// add the passed value to the dictionary at location k
if (!items[k]) {
items[k]=new dojo.collections.DictionaryEntry(k,v);
this.count=q.push(items[k]);
q.sort(sorter);
}
};
this.clear=function(){
// summary
// clear the internal collections
items={};
q=[];
this.count=q.length;
};
this.clone=function(){
// summary
// create a clone of this sorted list
return new dojo.collections.SortedList(this); // dojo.collections.SortedList
};
this.contains=this.containsKey=function(/* string */ k){
// summary
// Check to see if the list has a location k
if(testObject[k]){
return false; // bool
}
return (items[k]!=null); // bool
};
this.containsValue=function(/* object */ o){
// summary
// Check to see if this list contains the passed object
var e=this.getIterator();
while (!e.atEnd()){
var item=e.get();
if(item.value==o){
return true; // bool
}
}
return false; // bool
};
this.copyTo=function(/* array */ arr, /* int */ i){
// summary
// copy the contents of the list into array arr at index i
var e=this.getIterator();
var idx=i;
while(!e.atEnd()){
arr.splice(idx,0,e.get());
idx++;
}
};
this.entry=function(/* string */ k){
// summary
// return the object at location k
return items[k]; // dojo.collections.DictionaryEntry
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(q, fn, s);
}else{
for(var i=0; i<q.length; i++){
fn.call(s, q[i], i, q);
}
}
};
this.getByIndex=function(/* int */ i){
// summary
// return the item at index i
return q[i].valueOf(); // object
};
this.getIterator=function(){
// summary
// get an iterator for this object
return new dojo.collections.DictionaryIterator(items); // dojo.collections.DictionaryIterator
};
this.getKey=function(/* int */ i){
// summary
// return the key of the item at index i
return q[i].key;
};
this.getKeyList=function(){
// summary
// return an array of the keys set in this list
var arr=[];
var e=this.getIterator();
while (!e.atEnd()){
arr.push(e.get().key);
}
return arr; // array
};
this.getValueList=function(){
// summary
// return an array of values in this list
var arr=[];
var e=this.getIterator();
while (!e.atEnd()){
arr.push(e.get().value);
}
return arr; // array
};
this.indexOfKey=function(/* string */ k){
// summary
// return the index of the passed key.
for (var i=0; i<q.length; i++){
if (q[i].key==k){
return i; // int
}
}
return -1; // int
};
this.indexOfValue=function(/* object */ o){
// summary
// return the first index of object o
for (var i=0; i<q.length; i++){
if (q[i].value==o){
return i; // int
}
}
return -1; // int
};
this.item=function(/* string */ k){
// summary
// return the value of the object at location k.
if(k in items && !testObject[k]){
return items[k].valueOf(); // object
}
return undefined; // object
};
this.remove=function(/* string */k){
// summary
// remove the item at location k and rebuild the internal collections.
delete items[k];
build();
this.count=q.length;
};
this.removeAt=function(/* int */ i){
// summary
// remove the item at index i, and rebuild the internal collections.
delete items[q[i].key];
build();
this.count=q.length;
};
this.replace=function(/* string */ k, /* object */ v){
// summary
// Replace an existing item if it's there, and add a new one if not.
if (!items[k]){
// we're adding a new object, return false
this.add(k,v);
return false; // bool
}else{
// we're replacing an object, return true
items[k]=new dojo.collections.DictionaryEntry(k,v);
q.sort(sorter);
return true; // bool
}
};
this.setByIndex=function(/* int */ i, /* object */ o){
// summary
// set an item by index
items[q[i].key].value=o;
build();
this.count=q.length;
};
if (dictionary){
var e=dictionary.getIterator();
while (!e.atEnd()){
var item=e.get();
q[q.length]=items[item.key]=new dojo.collections.DictionaryEntry(item.key,item.value);
}
q.sort(sorter);
}
}

View file

@ -0,0 +1,85 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Stack");
dojo.require("dojo.collections.Collections");
dojo.collections.Stack=function(/* array? */arr){
// summary
// returns an object of type dojo.collections.Stack
var q=[];
if (arr) q=q.concat(arr);
this.count=q.length;
this.clear=function(){
// summary
// Clear the internal array and reset the count
q=[];
this.count=q.length;
};
this.clone=function(){
// summary
// Create and return a clone of this Stack
return new dojo.collections.Stack(q);
};
this.contains=function(/* object */o){
// summary
// check to see if the stack contains object o
for (var i=0; i<q.length; i++){
if (q[i] == o){
return true; // bool
}
}
return false; // bool
};
this.copyTo=function(/* array */ arr, /* int */ i){
// summary
// copy the stack into array arr at index i
arr.splice(i,0,q);
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(q, fn, s);
}else{
for(var i=0; i<q.length; i++){
fn.call(s, q[i], i, q);
}
}
};
this.getIterator=function(){
// summary
// get an iterator for this collection
return new dojo.collections.Iterator(q); // dojo.collections.Iterator
};
this.peek=function(){
// summary
// Return the next item without altering the stack itself.
return q[(q.length-1)]; // object
};
this.pop=function(){
// summary
// pop and return the next item on the stack
var r=q.pop();
this.count=q.length;
return r; // object
};
this.push=function(/* object */ o){
// summary
// Push object o onto the stack
this.count=q.push(o);
};
this.toArray=function(){
// summary
// create and return an array based on the internal collection
return [].concat(q); // array
};
}

View file

@ -0,0 +1,22 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: [
"dojo.collections.Collections",
"dojo.collections.SortedList",
"dojo.collections.Dictionary",
"dojo.collections.Queue",
"dojo.collections.ArrayList",
"dojo.collections.Stack",
"dojo.collections.Set"
]
});
dojo.provide("dojo.collections.*");

View file

@ -0,0 +1,75 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/*
Compatibility package to get 0.2.2 functionality in later Dojo releases.
*/
//**********************************
//From bootstrap1.js
dj_throw = dj_rethrow = function(m, e){
dojo.deprecated("dj_throw and dj_rethrow", "use dojo.raise instead", "0.4");
dojo.raise(m, e);
}
dj_debug = dojo.debug;
dj_unimplemented = dojo.unimplemented;
dj_deprecated = dojo.deprecated;
dj_inherits = function(subclass, superclass){
dojo.deprecated("dj_inherits", "use dojo.inherits instead", "0.4");
dojo.inherits(subclass, superclass);
}
/**
* Set the base script uri.
*/
// In JScript .NET, see interface System._AppDomain implemented by
// System.AppDomain.CurrentDomain. Members include AppendPrivatePath,
// RelativeSearchPath, BaseDirectory.
dojo.hostenv.setBaseScriptUri = function(uri){ djConfig.baseScriptUri = uri }
//**********************************
//From the old bootstrap2.js
dojo.hostenv.moduleLoaded = function(){
return dojo.hostenv.startPackage.apply(dojo.hostenv, arguments);
}
dojo.hostenv.require = dojo.hostenv.loadModule;
dojo.requireAfter = dojo.require;
dojo.conditionalRequire = dojo.requireIf;
dojo.requireAll = function() {
for(var i = 0; i < arguments.length; i++) { dojo.require(arguments[i]); }
}
dojo.hostenv.conditionalLoadModule = function(){
dojo.kwCompoundRequire.apply(dojo, arguments);
}
dojo.hostenv.provide = dojo.hostenv.startPackage;
//**********************************
//From hostenv_browser.js
dojo.hostenv.byId = dojo.byId;
dojo.hostenv.byIdArray = dojo.byIdArray = function(){
var ids = [];
for(var i = 0; i < arguments.length; i++){
if((arguments[i] instanceof Array)||(typeof arguments[i] == "array")){
for(var j = 0; j < arguments[i].length; j++){
ids = ids.concat(dojo.hostenv.byIdArray(arguments[i][j]));
}
}else{
ids.push(dojo.hostenv.byId(arguments[i]));
}
}
return ids;
}

15
webapp/web/src/crypto.js Normal file
View file

@ -0,0 +1,15 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.crypto");
// enumerations for use in crypto code. Note that 0 == default, for the most part.
dojo.crypto.cipherModes={ ECB:0, CBC:1, PCBC:2, CFB:3, OFB:4, CTR:5 };
dojo.crypto.outputTypes={ Base64:0,Hex:1,String:2,Raw:3 };

View file

@ -0,0 +1,548 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.crypto");
dojo.provide("dojo.crypto.Blowfish");
/* Blowfish
* Created based on the C# implementation by Marcus Hahn (http://www.hotpixel.net/)
* Unsigned math functions derived from Joe Gregorio's SecureSyndication GM script
* http://bitworking.org/projects/securesyndication/
* (Note that this is *not* an adaption of the above script)
*
* version 1.0
* TRT
* 2005-12-08
*/
dojo.crypto.Blowfish = new function(){
var POW2=Math.pow(2,2);
var POW3=Math.pow(2,3);
var POW4=Math.pow(2,4);
var POW8=Math.pow(2,8);
var POW16=Math.pow(2,16);
var POW24=Math.pow(2,24);
var iv=null; // CBC mode initialization vector
var boxes={
p:[
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
],
s0:[
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
],
s1:[
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
],
s2:[
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
],
s3:[
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
]
}
////////////////////////////////////////////////////////////////////////////
function add(x,y){
var sum=(x+y)&0xffffffff;
if (sum<0){
sum=-sum;
return (0x10000*((sum>>16)^0xffff))+(((sum&0xffff)^0xffff)+1);
}
return sum;
}
function split(x){
var r=x&0xffffffff;
if(r<0) {
r=-r;
return [((r&0xffff)^0xffff)+1,(r>>16)^0xffff];
}
return [r&0xffff,(r>>16)];
}
function xor(x,y){
var xs=split(x);
var ys=split(y);
return (0x10000*(xs[1]^ys[1]))+(xs[0]^ys[0]);
}
function $(v, box){
var d=v&0xff; v>>=8;
var c=v&0xff; v>>=8;
var b=v&0xff; v>>=8;
var a=v&0xff;
var r=add(box.s0[a],box.s1[b]);
r=xor(r,box.s2[c]);
return add(r,box.s3[d]);
}
////////////////////////////////////////////////////////////////////////////
function eb(o, box){
var l=o.left;
var r=o.right;
l=xor(l,box.p[0]);
r=xor(r,xor($(l,box),box.p[1]));
l=xor(l,xor($(r,box),box.p[2]));
r=xor(r,xor($(l,box),box.p[3]));
l=xor(l,xor($(r,box),box.p[4]));
r=xor(r,xor($(l,box),box.p[5]));
l=xor(l,xor($(r,box),box.p[6]));
r=xor(r,xor($(l,box),box.p[7]));
l=xor(l,xor($(r,box),box.p[8]));
r=xor(r,xor($(l,box),box.p[9]));
l=xor(l,xor($(r,box),box.p[10]));
r=xor(r,xor($(l,box),box.p[11]));
l=xor(l,xor($(r,box),box.p[12]));
r=xor(r,xor($(l,box),box.p[13]));
l=xor(l,xor($(r,box),box.p[14]));
r=xor(r,xor($(l,box),box.p[15]));
l=xor(l,xor($(r,box),box.p[16]));
o.right=l;
o.left=xor(r,box.p[17]);
}
function db(o, box){
var l=o.left;
var r=o.right;
l=xor(l,box.p[17]);
r=xor(r,xor($(l,box),box.p[16]));
l=xor(l,xor($(r,box),box.p[15]));
r=xor(r,xor($(l,box),box.p[14]));
l=xor(l,xor($(r,box),box.p[13]));
r=xor(r,xor($(l,box),box.p[12]));
l=xor(l,xor($(r,box),box.p[11]));
r=xor(r,xor($(l,box),box.p[10]));
l=xor(l,xor($(r,box),box.p[9]));
r=xor(r,xor($(l,box),box.p[8]));
l=xor(l,xor($(r,box),box.p[7]));
r=xor(r,xor($(l,box),box.p[6]));
l=xor(l,xor($(r,box),box.p[5]));
r=xor(r,xor($(l,box),box.p[4]));
l=xor(l,xor($(r,box),box.p[3]));
r=xor(r,xor($(l,box),box.p[2]));
l=xor(l,xor($(r,box),box.p[1]));
o.right=l;
o.left=xor(r,box.p[0]);
}
// Note that we aren't caching contexts here; it might take a little longer
// but we should be more secure this way.
function init(key){
var k=key;
if (typeof(k)=="string"){
var a=[];
for(var i=0; i<k.length; i++)
a.push(k.charCodeAt(i)&0xff);
k=a;
}
// init the boxes
var box = { p:[], s0:[], s1:[], s2:[], s3:[] };
for(var i=0; i<boxes.p.length; i++) box.p.push(boxes.p[i]);
for(var i=0; i<boxes.s0.length; i++) box.s0.push(boxes.s0[i]);
for(var i=0; i<boxes.s1.length; i++) box.s1.push(boxes.s1[i]);
for(var i=0; i<boxes.s2.length; i++) box.s2.push(boxes.s2[i]);
for(var i=0; i<boxes.s3.length; i++) box.s3.push(boxes.s3[i]);
// init p with the key
var pos=0;
var data=0;
for(var i=0; i < box.p.length; i++){
for (var j=0; j<4; j++){
data = (data*POW8) | k[pos];
if(++pos==k.length) pos=0;
}
box.p[i] = xor(box.p[i], data);
}
// encrypt p and the s boxes
var res={ left:0, right:0 };
for(var i=0; i<box.p.length;){
eb(res, box);
box.p[i++]=res.left;
box.p[i++]=res.right;
}
for (var i=0; i<4; i++){
for(var j=0; j<box["s"+i].length;){
eb(res, box);
box["s"+i][j++]=res.left;
box["s"+i][j++]=res.right;
}
}
return box;
}
////////////////////////////////////////////////////////////////////////////
// CONVERSION FUNCTIONS
////////////////////////////////////////////////////////////////////////////
// these operate on byte arrays, NOT word arrays.
function toBase64(ba){
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var s=[];
var count=0;
for (var i =0; i<ba.length;){
var t=ba[i++]<<16|ba[i++]<<8|ba[i++];
s.push(tab.charAt((t>>>18)&0x3f));
s.push(tab.charAt((t>>>12)&0x3f));
s.push(tab.charAt((t>>>6)&0x3f));
s.push(tab.charAt(t&0x3f));
count+=4;
}
var pa=i-ba.length;
while((pa--)>0) s.push(p);
return s.join("");
}
function fromBase64(str){
var s=str.split("");
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var out=[];
var l=s.length;
while(s[--l]==p){ }
for (var i=0; i<l;){
var t=tab.indexOf(s[i++])<<18|tab.indexOf(s[i++])<<12|tab.indexOf(s[i++])<<6|tab.indexOf(s[i++]);
out.push((t>>>16)&0xff);
out.push((t>>>8)&0xff);
out.push(t&0xff);
}
return out;
}
////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS
// 0.2: Only supporting ECB mode for now.
////////////////////////////////////////////////////////////////////////////
this.getIV=function(outputType){
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
var s=[];
for(var i=0; i<iv.length; i++)
s.push((iv[i]).toString(16));
return s.join("");
}
case dojo.crypto.outputTypes.String:{
return iv.join("");
}
case dojo.crypto.outputTypes.Raw:{
return iv;
}
default:{
return toBase64(iv);
}
}
};
this.setIV=function(data, inputType){
var ip=inputType||dojo.crypto.outputTypes.Base64;
var ba=null;
switch(ip){
case dojo.crypto.outputTypes.String:{
ba=[];
for (var i=0; i<data.length; i++){
ba.push(data.charCodeAt(i));
}
break;
}
case dojo.crypto.outputTypes.Hex:{
ba=[];
var i=0;
while (i+1<data.length){
ba.push(parseInt(data.substr(i,2),16));
i+=2;
}
break;
}
case dojo.crypto.outputTypes.Raw:{
ba=data;
break;
}
default:{
ba=fromBase64(data);
break;
}
}
// make it a pair of words now
iv={};
iv.left=ba[0]*POW24|ba[1]*POW16|ba[2]*POW8|ba[3];
iv.right=ba[4]*POW24|ba[5]*POW16|ba[6]*POW8|ba[7];
}
this.encrypt = function(plaintext, key, ao){
var out=dojo.crypto.outputTypes.Base64;
var mode=dojo.crypto.cipherModes.EBC;
if (ao){
if (ao.outputType) out=ao.outputType;
if (ao.cipherMode) mode=ao.cipherMode;
}
var bx = init(key);
var padding = 8-(plaintext.length&7);
for (var i=0; i<padding; i++) plaintext+=String.fromCharCode(padding);
var cipher=[];
var count=plaintext.length >> 3;
var pos=0;
var o={};
var isCBC=(mode==dojo.crypto.cipherModes.CBC);
var vector={left:iv.left||null, right:iv.right||null};
for(var i=0; i<count; i++){
o.left=plaintext.charCodeAt(pos)*POW24
|plaintext.charCodeAt(pos+1)*POW16
|plaintext.charCodeAt(pos+2)*POW8
|plaintext.charCodeAt(pos+3);
o.right=plaintext.charCodeAt(pos+4)*POW24
|plaintext.charCodeAt(pos+5)*POW16
|plaintext.charCodeAt(pos+6)*POW8
|plaintext.charCodeAt(pos+7);
if(isCBC){
o.left=xor(o.left, vector.left);
o.right=xor(o.right, vector.right);
}
eb(o, bx); // encrypt the block
if(isCBC){
vector.left=o.left;
vector.right=o.right;dojo.crypto.outputTypes.Hex
}
cipher.push((o.left>>24)&0xff);
cipher.push((o.left>>16)&0xff);
cipher.push((o.left>>8)&0xff);
cipher.push(o.left&0xff);
cipher.push((o.right>>24)&0xff);
cipher.push((o.right>>16)&0xff);
cipher.push((o.right>>8)&0xff);
cipher.push(o.right&0xff);
pos+=8;
}
switch(out){
case dojo.crypto.outputTypes.Hex:{
var s=[];
for(var i=0; i<cipher.length; i++)
s.push((cipher[i]).toString(16));
return s.join("");
}
case dojo.crypto.outputTypes.String:{
return cipher.join("");
}
case dojo.crypto.outputTypes.Raw:{
return cipher;
}
default:{
return toBase64(cipher);
}
}
};
this.decrypt = function(ciphertext, key, ao){
var ip=dojo.crypto.outputTypes.Base64;
var mode=dojo.crypto.cipherModes.EBC;
if (ao){
if (ao.outputType) ip=ao.outputType;
if (ao.cipherMode) mode=ao.cipherMode;
}
var bx = init(key);
var pt=[];
var c=null;
switch(ip){
case dojo.crypto.outputTypes.Hex:{
c=[];
var i=0;
while (i+1<ciphertext.length){
c.push(parseInt(ciphertext.substr(i,2),16));
i+=2;
}
break;
}
case dojo.crypto.outputTypes.String:{
c=[];
for (var i=0; i<ciphertext.length; i++){
c.push(ciphertext.charCodeAt(i));
}
break;
}
case dojo.crypto.outputTypes.Raw:{
c=ciphertext; // should be a byte array
break;
}
default:{
c=fromBase64(ciphertext);
break;
}
}
var count=c.length >> 3;
var pos=0;
var o={};
var isCBC=(mode==dojo.crypto.cipherModes.CBC);
var vector={left:iv.left||null, right:iv.right||null};
for(var i=0; i<count; i++){
o.left=c[pos]*POW24|c[pos+1]*POW16|c[pos+2]*POW8|c[pos+3];
o.right=c[pos+4]*POW24|c[pos+5]*POW16|c[pos+6]*POW8|c[pos+7];
if(isCBC){
var left=o.left;
var right=o.right;
}
db(o, bx); // decrypt the block
if(isCBC){
o.left=xor(o.left, vector.left);
o.right=xor(o.right, vector.right);
vector.left=left;
vector.right=right;
}
pt.push((o.left>>24)&0xff);
pt.push((o.left>>16)&0xff);
pt.push((o.left>>8)&0xff);
pt.push(o.left&0xff);
pt.push((o.right>>24)&0xff);
pt.push((o.right>>16)&0xff);
pt.push((o.right>>8)&0xff);
pt.push(o.right&0xff);
pos+=8;
}
// check for padding, and remove.
if(pt[pt.length-1]==pt[pt.length-2]||pt[pt.length-1]==0x01){
var n=pt[pt.length-1];
pt.splice(pt.length-n, n);
}
// convert to string
for(var i=0; i<pt.length; i++)
pt[i]=String.fromCharCode(pt[i]);
return pt.join("");
};
this.setIV("0000000000000000", dojo.crypto.outputTypes.Hex);
}();

View file

@ -0,0 +1,11 @@
License Disclaimer:
All contents of this directory are Copyright (c) the Dojo Foundation, with the
following exceptions:
-------------------------------------------------------------------------------
MD5.js, SHA1.js:
* Copyright 1998-2005, Paul Johnstone
Distributed under the terms of the BSD License

View file

@ -0,0 +1,193 @@
dojo.require("dojo.crypto");
dojo.provide("dojo.crypto.MD5");
/* Return to a port of Paul Johnstone's MD5 implementation
* http://pajhome.org.uk/crypt/md5/index.html
*
* Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
*
* Dojo port by Tom Trenka
*
* 2005-12-7
* All conversions are internalized (no dependencies)
* implemented getHMAC for message digest auth.
*/
dojo.crypto.MD5 = new function(){
var chrsz=8;
var mask=(1<<chrsz)-1;
function toWord(s) {
var wa=[];
for(var i=0; i<s.length*chrsz; i+=chrsz)
wa[i>>5]|=(s.charCodeAt(i/chrsz)&mask)<<(i%32);
return wa;
}
function toString(wa){
var s=[];
for(var i=0; i<wa.length*32; i+=chrsz)
s.push(String.fromCharCode((wa[i>>5]>>>(i%32))&mask));
return s.join("");
}
function toHex(wa) {
var h="0123456789abcdef";
var s=[];
for(var i=0; i<wa.length*4; i++){
s.push(h.charAt((wa[i>>2]>>((i%4)*8+4))&0xF)+h.charAt((wa[i>>2]>>((i%4)*8))&0xF));
}
return s.join("");
}
function toBase64(wa){
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var s=[];
for(var i=0; i<wa.length*4; i+=3){
var t=(((wa[i>>2]>>8*(i%4))&0xFF)<<16)|(((wa[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((wa[i+2>>2]>>8*((i+2)%4))&0xFF);
for(var j=0; j<4; j++){
if(i*8+j*6>wa.length*32) s.push(p);
else s.push(tab.charAt((t>>6*(3-j))&0x3F));
}
}
return s.join("");
}
function add(x,y) {
var l=(x&0xFFFF)+(y&0xFFFF);
var m=(x>>16)+(y>>16)+(l>>16);
return (m<<16)|(l&0xFFFF);
}
function R(n,c){ return (n<<c)|(n>>>(32-c)); }
function C(q,a,b,x,s,t){ return add(R(add(add(a,q),add(x,t)),s),b); }
function FF(a,b,c,d,x,s,t){ return C((b&c)|((~b)&d),a,b,x,s,t); }
function GG(a,b,c,d,x,s,t){ return C((b&d)|(c&(~d)),a,b,x,s,t); }
function HH(a,b,c,d,x,s,t){ return C(b^c^d,a,b,x,s,t); }
function II(a,b,c,d,x,s,t){ return C(c^(b|(~d)),a,b,x,s,t); }
function core(x,len){
x[len>>5]|=0x80<<((len)%32);
x[(((len+64)>>>9)<<4)+14]=len;
var a= 1732584193;
var b=-271733879;
var c=-1732584194;
var d= 271733878;
for(var i=0; i<x.length; i+=16){
var olda=a;
var oldb=b;
var oldc=c;
var oldd=d;
a=FF(a,b,c,d,x[i+ 0],7 ,-680876936);
d=FF(d,a,b,c,x[i+ 1],12,-389564586);
c=FF(c,d,a,b,x[i+ 2],17, 606105819);
b=FF(b,c,d,a,x[i+ 3],22,-1044525330);
a=FF(a,b,c,d,x[i+ 4],7 ,-176418897);
d=FF(d,a,b,c,x[i+ 5],12, 1200080426);
c=FF(c,d,a,b,x[i+ 6],17,-1473231341);
b=FF(b,c,d,a,x[i+ 7],22,-45705983);
a=FF(a,b,c,d,x[i+ 8],7 , 1770035416);
d=FF(d,a,b,c,x[i+ 9],12,-1958414417);
c=FF(c,d,a,b,x[i+10],17,-42063);
b=FF(b,c,d,a,x[i+11],22,-1990404162);
a=FF(a,b,c,d,x[i+12],7 , 1804603682);
d=FF(d,a,b,c,x[i+13],12,-40341101);
c=FF(c,d,a,b,x[i+14],17,-1502002290);
b=FF(b,c,d,a,x[i+15],22, 1236535329);
a=GG(a,b,c,d,x[i+ 1],5 ,-165796510);
d=GG(d,a,b,c,x[i+ 6],9 ,-1069501632);
c=GG(c,d,a,b,x[i+11],14, 643717713);
b=GG(b,c,d,a,x[i+ 0],20,-373897302);
a=GG(a,b,c,d,x[i+ 5],5 ,-701558691);
d=GG(d,a,b,c,x[i+10],9 , 38016083);
c=GG(c,d,a,b,x[i+15],14,-660478335);
b=GG(b,c,d,a,x[i+ 4],20,-405537848);
a=GG(a,b,c,d,x[i+ 9],5 , 568446438);
d=GG(d,a,b,c,x[i+14],9 ,-1019803690);
c=GG(c,d,a,b,x[i+ 3],14,-187363961);
b=GG(b,c,d,a,x[i+ 8],20, 1163531501);
a=GG(a,b,c,d,x[i+13],5 ,-1444681467);
d=GG(d,a,b,c,x[i+ 2],9 ,-51403784);
c=GG(c,d,a,b,x[i+ 7],14, 1735328473);
b=GG(b,c,d,a,x[i+12],20,-1926607734);
a=HH(a,b,c,d,x[i+ 5],4 ,-378558);
d=HH(d,a,b,c,x[i+ 8],11,-2022574463);
c=HH(c,d,a,b,x[i+11],16, 1839030562);
b=HH(b,c,d,a,x[i+14],23,-35309556);
a=HH(a,b,c,d,x[i+ 1],4 ,-1530992060);
d=HH(d,a,b,c,x[i+ 4],11, 1272893353);
c=HH(c,d,a,b,x[i+ 7],16,-155497632);
b=HH(b,c,d,a,x[i+10],23,-1094730640);
a=HH(a,b,c,d,x[i+13],4 , 681279174);
d=HH(d,a,b,c,x[i+ 0],11,-358537222);
c=HH(c,d,a,b,x[i+ 3],16,-722521979);
b=HH(b,c,d,a,x[i+ 6],23, 76029189);
a=HH(a,b,c,d,x[i+ 9],4 ,-640364487);
d=HH(d,a,b,c,x[i+12],11,-421815835);
c=HH(c,d,a,b,x[i+15],16, 530742520);
b=HH(b,c,d,a,x[i+ 2],23,-995338651);
a=II(a,b,c,d,x[i+ 0],6 ,-198630844);
d=II(d,a,b,c,x[i+ 7],10, 1126891415);
c=II(c,d,a,b,x[i+14],15,-1416354905);
b=II(b,c,d,a,x[i+ 5],21,-57434055);
a=II(a,b,c,d,x[i+12],6 , 1700485571);
d=II(d,a,b,c,x[i+ 3],10,-1894986606);
c=II(c,d,a,b,x[i+10],15,-1051523);
b=II(b,c,d,a,x[i+ 1],21,-2054922799);
a=II(a,b,c,d,x[i+ 8],6 , 1873313359);
d=II(d,a,b,c,x[i+15],10,-30611744);
c=II(c,d,a,b,x[i+ 6],15,-1560198380);
b=II(b,c,d,a,x[i+13],21, 1309151649);
a=II(a,b,c,d,x[i+ 4],6 ,-145523070);
d=II(d,a,b,c,x[i+11],10,-1120210379);
c=II(c,d,a,b,x[i+ 2],15, 718787259);
b=II(b,c,d,a,x[i+ 9],21,-343485551);
a = add(a,olda);
b = add(b,oldb);
c = add(c,oldc);
d = add(d,oldd);
}
return [a,b,c,d];
}
function hmac(data,key){
var wa=toWord(key);
if(wa.length>16) wa=core(wa,key.length*chrsz);
var l=[], r=[];
for(var i=0; i<16; i++){
l[i]=wa[i]^0x36363636;
r[i]=wa[i]^0x5c5c5c5c;
}
var h=core(l.concat(toWord(data)),512+data.length*chrsz);
return core(r.concat(h),640);
}
// Public functions
this.compute=function(data,outputType){
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(core(toWord(data),data.length*chrsz));
}
case dojo.crypto.outputTypes.String:{
return toString(core(toWord(data),data.length*chrsz));
}
default:{
return toBase64(core(toWord(data),data.length*chrsz));
}
}
};
this.getHMAC=function(data,key,outputType){
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(hmac(data,key));
}
case dojo.crypto.outputTypes.String:{
return toString(hmac(data,key));
}
default:{
return toBase64(hmac(data,key));
}
}
};
}();

View file

@ -0,0 +1,22 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.crypto.Rijndael");
dojo.require("dojo.crypto");
dojo.require("dojo.experimental");
dojo.experimental("dojo.crypto.Rijndael");
dojo.crypto.Rijndael = new function(){
this.encrypt=function(plaintext, key){
};
this.decrypt=function(ciphertext, key){
};
}();

View file

@ -0,0 +1,154 @@
dojo.require("dojo.crypto");
dojo.provide("dojo.crypto.SHA1");
dojo.require("dojo.experimental");
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS PUB 180-1
*
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*
* Dojo port by Tom Trenka
*/
dojo.experimental("dojo.crypto.SHA1");
dojo.crypto.SHA1 = new function(){
var chrsz=8;
var mask=(1<<chrsz)-1;
function toWord(s) {
var wa=[];
for(var i=0; i<s.length*chrsz; i+=chrsz)
wa[i>>5]|=(s.charCodeAt(i/chrsz)&mask)<<(i%32);
return wa;
}
function toString(wa){
var s=[];
for(var i=0; i<wa.length*32; i+=chrsz)
s.push(String.fromCharCode((wa[i>>5]>>>(i%32))&mask));
return s.join("");
}
function toHex(wa) {
var h="0123456789abcdef";
var s=[];
for(var i=0; i<wa.length*4; i++){
s.push(h.charAt((wa[i>>2]>>((i%4)*8+4))&0xF)+h.charAt((wa[i>>2]>>((i%4)*8))&0xF));
}
return s.join("");
}
function toBase64(wa){
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var s=[];
for(var i=0; i<wa.length*4; i+=3){
var t=(((wa[i>>2]>>8*(i%4))&0xFF)<<16)|(((wa[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((wa[i+2>>2]>>8*((i+2)%4))&0xFF);
for(var j=0; j<4; j++){
if(i*8+j*6>wa.length*32) s.push(p);
else s.push(tab.charAt((t>>6*(3-j))&0x3F));
}
}
return s.join("");
}
// math
function add(x,y){
var l=(x&0xffff)+(y&0xffff);
var m=(x>>16)+(y>>16)+(l>>16);
return (m<<16)|(l&0xffff);
}
function r(x,n){ return (x<<n)|(x>>>(32-n)); }
// SHA rounds
function f(u,v,w){ return ((u&v)|(~u&w)); }
function g(u,v,w){ return ((u&v)|(u&w)|(v&w)); }
function h(u,v,w){ return (u^v^w); }
function fn(i,u,v,w){
if(i<20) return f(u,v,w);
if(i<40) return h(u,v,w);
if(i<60) return g(u,v,w);
return h(u,v,w);
}
function cnst(i){
if(i<20) return 1518500249;
if(i<40) return 1859775393;
if(i<60) return -1894007588;
return -899497514;
}
function core(x,len){
x[len>>5]|=0x80<<(24-len%32);
x[((len+64>>9)<<4)+15]=len;
var w=[];
var a= 1732584193; // 0x67452301
var b=-271733879; // 0xefcdab89
var c=-1732584194; // 0x98badcfe
var d= 271733878; // 0x10325476
var e=-1009589776; // 0xc3d2e1f0
for(var i=0; i<x.length; i+=16){
var olda=a;
var oldb=b;
var oldc=c;
var oldd=d;
var olde=e;
for(var j=0; j<80; j++){
if(j<16) w[j]=x[i+j];
else w[j]=r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);
var t=add(add(r(a,5),fn(j,b,c,d)),add(add(e,w[j]),cnst(j)));
e=d; d=c; c=r(b,30); b=a; a=t;
}
a=add(a,olda);
b=add(b,oldb);
c=add(c,oldc);
d=add(d,oldd);
e=add(e,olde);
}
return [a,b,c,d,e];
}
function hmac(data,key){
var wa=toWord(key);
if(wa.length>16) wa=core(wa,key.length*chrsz);
var l=[], r=[];
for(var i=0; i<16; i++){
l[i]=wa[i]^0x36363636;
r[i]=wa[i]^0x5c5c5c5c;
}
var h=core(l.concat(toWord(data)),512+data.length*chrsz);
return core(r.concat(h),640);
}
this.compute=function(data,outputType){
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(core(toWord(data),data.length*chrsz));
}
case dojo.crypto.outputTypes.String:{
return toString(core(toWord(data),data.length*chrsz));
}
default:{
return toBase64(core(toWord(data),data.length*chrsz));
}
}
};
this.getHMAC=function(data,key,outputType){
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(hmac(data,key));
}
case dojo.crypto.outputTypes.String:{
return toString(hmac(data,key));
}
default:{
return toBase64(hmac(data,key));
}
}
};
}();

View file

@ -0,0 +1,20 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.crypto.SHA256");
dojo.require("dojo.crypto");
dojo.require("dojo.experimental");
dojo.experimental("dojo.crypto.SHA256");
dojo.crypto.SHA256 = new function(){
this.compute=function(s){
};
}();

View file

@ -0,0 +1,17 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: [
"dojo.crypto",
"dojo.crypto.MD5"
]
});
dojo.provide("dojo.crypto.*");

15
webapp/web/src/data.js Normal file
View file

@ -0,0 +1,15 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data");
// currently a stub for dojo.data
dojo.data = {};

View file

@ -0,0 +1,62 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Attribute");
dojo.require("dojo.data.Item");
dojo.require("dojo.lang.assert");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.Attribute = function(/* dojo.data.provider.Base */ dataProvider, /* string */ attributeId) {
/**
* summary:
* An Attribute object represents something like a column in
* a relational database.
*/
dojo.lang.assertType(dataProvider, [dojo.data.provider.Base, "optional"]);
dojo.lang.assertType(attributeId, String);
dojo.data.Item.call(this, dataProvider);
this._attributeId = attributeId;
};
dojo.inherits(dojo.data.Attribute, dojo.data.Item);
// -------------------------------------------------------------------
// Public instance methods
// -------------------------------------------------------------------
dojo.data.Attribute.prototype.toString = function() {
return this._attributeId; // string
};
dojo.data.Attribute.prototype.getAttributeId = function() {
/**
* summary:
* Returns the string token that uniquely identifies this
* attribute within the context of a data provider.
* For a data provider that accesses relational databases,
* typical attributeIds might be tokens like "name", "age",
* "ssn", or "dept_key".
*/
return this._attributeId; // string
};
dojo.data.Attribute.prototype.getType = function() {
/**
* summary: Returns the data type of the values of this attribute.
*/
return this.get('type'); // dojo.data.Type or null
};
dojo.data.Attribute.prototype.setType = function(/* dojo.data.Type or null */ type) {
/**
* summary: Sets the data type for this attribute.
*/
this.set('type', type);
};

332
webapp/web/src/data/Item.js Normal file
View file

@ -0,0 +1,332 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Item");
dojo.require("dojo.data.Observable");
dojo.require("dojo.data.Value");
dojo.require("dojo.lang.common");
dojo.require("dojo.lang.assert");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.Item = function(/* dojo.data.provider.Base */ dataProvider) {
/**
* summary:
* An Item has attributes and attribute values, sort of like
* a record in a database, or a 'struct' in C. Instances of
* the Item class know how to store and retrieve their
* attribute values.
*/
dojo.lang.assertType(dataProvider, [dojo.data.provider.Base, "optional"]);
dojo.data.Observable.call(this);
this._dataProvider = dataProvider;
this._dictionaryOfAttributeValues = {};
};
dojo.inherits(dojo.data.Item, dojo.data.Observable);
// -------------------------------------------------------------------
// Public class methods
// -------------------------------------------------------------------
dojo.data.Item.compare = function(/* dojo.data.Item */ itemOne, /* dojo.data.Item */ itemTwo) {
/**
* summary:
* Given two Items to compare, this method returns 0, 1, or -1.
* This method is designed to be used by sorting routines, like
* the JavaScript built-in Array sort() method.
*
* Example:
* <pre>
* var a = dataProvider.newItem("kermit");
* var b = dataProvider.newItem("elmo");
* var c = dataProvider.newItem("grover");
* var array = new Array(a, b, c);
* array.sort(dojo.data.Item.compare);
* </pre>
*/
dojo.lang.assertType(itemOne, dojo.data.Item);
if (!dojo.lang.isOfType(itemTwo, dojo.data.Item)) {
return -1;
}
var nameOne = itemOne.getName();
var nameTwo = itemTwo.getName();
if (nameOne == nameTwo) {
var attributeArrayOne = itemOne.getAttributes();
var attributeArrayTwo = itemTwo.getAttributes();
if (attributeArrayOne.length != attributeArrayTwo.length) {
if (attributeArrayOne.length > attributeArrayTwo.length) {
return 1;
} else {
return -1;
}
}
for (var i in attributeArrayOne) {
var attribute = attributeArrayOne[i];
var arrayOfValuesOne = itemOne.getValues(attribute);
var arrayOfValuesTwo = itemTwo.getValues(attribute);
dojo.lang.assert(arrayOfValuesOne && (arrayOfValuesOne.length > 0));
if (!arrayOfValuesTwo) {
return 1;
}
if (arrayOfValuesOne.length != arrayOfValuesTwo.length) {
if (arrayOfValuesOne.length > arrayOfValuesTwo.length) {
return 1;
} else {
return -1;
}
}
for (var j in arrayOfValuesOne) {
var value = arrayOfValuesOne[j];
if (!itemTwo.hasAttributeValue(value)) {
return 1;
}
}
return 0;
}
} else {
if (nameOne > nameTwo) {
return 1;
} else {
return -1; // 0, 1, or -1
}
}
};
// -------------------------------------------------------------------
// Public instance methods
// -------------------------------------------------------------------
dojo.data.Item.prototype.toString = function() {
/**
* Returns a simple string representation of the item.
*/
var arrayOfStrings = [];
var attributes = this.getAttributes();
for (var i in attributes) {
var attribute = attributes[i];
var arrayOfValues = this.getValues(attribute);
var valueString;
if (arrayOfValues.length == 1) {
valueString = arrayOfValues[0];
} else {
valueString = '[';
valueString += arrayOfValues.join(', ');
valueString += ']';
}
arrayOfStrings.push(' ' + attribute + ': ' + valueString);
}
var returnString = '{ ';
returnString += arrayOfStrings.join(',\n');
returnString += ' }';
return returnString; // string
};
dojo.data.Item.prototype.compare = function(/* dojo.data.Item */ otherItem) {
/**
* summary: Compares this Item to another Item, and returns 0, 1, or -1.
*/
return dojo.data.Item.compare(this, otherItem); // 0, 1, or -1
};
dojo.data.Item.prototype.isEqual = function(/* dojo.data.Item */ otherItem) {
/**
* summary: Returns true if this Item is equal to the otherItem, or false otherwise.
*/
return (this.compare(otherItem) == 0); // boolean
};
dojo.data.Item.prototype.getName = function() {
return this.get('name');
};
dojo.data.Item.prototype.get = function(/* string or dojo.data.Attribute */ attributeId) {
/**
* summary: Returns a single literal value, like "foo" or 33.
*/
// dojo.lang.assertType(attributeId, [String, dojo.data.Attribute]);
var literalOrValueOrArray = this._dictionaryOfAttributeValues[attributeId];
if (dojo.lang.isUndefined(literalOrValueOrArray)) {
return null; // null
}
if (literalOrValueOrArray instanceof dojo.data.Value) {
return literalOrValueOrArray.getValue(); // literal
}
if (dojo.lang.isArray(literalOrValueOrArray)) {
var dojoDataValue = literalOrValueOrArray[0];
return dojoDataValue.getValue(); // literal
}
return literalOrValueOrArray; // literal
};
dojo.data.Item.prototype.getValue = function(/* string or dojo.data.Attribute */ attributeId) {
/**
* summary: Returns a single instance of dojo.data.Value.
*/
// dojo.lang.assertType(attributeId, [String, dojo.data.Attribute]);
var literalOrValueOrArray = this._dictionaryOfAttributeValues[attributeId];
if (dojo.lang.isUndefined(literalOrValueOrArray)) {
return null; // null
}
if (literalOrValueOrArray instanceof dojo.data.Value) {
return literalOrValueOrArray; // dojo.data.Value
}
if (dojo.lang.isArray(literalOrValueOrArray)) {
var dojoDataValue = literalOrValueOrArray[0];
return dojoDataValue; // dojo.data.Value
}
var literal = literalOrValueOrArray;
dojoDataValue = new dojo.data.Value(literal);
this._dictionaryOfAttributeValues[attributeId] = dojoDataValue;
return dojoDataValue; // dojo.data.Value
};
dojo.data.Item.prototype.getValues = function(/* string or dojo.data.Attribute */ attributeId) {
/**
* summary: Returns an array of dojo.data.Value objects.
*/
// dojo.lang.assertType(attributeId, [String, dojo.data.Attribute]);
var literalOrValueOrArray = this._dictionaryOfAttributeValues[attributeId];
if (dojo.lang.isUndefined(literalOrValueOrArray)) {
return null; // null
}
if (literalOrValueOrArray instanceof dojo.data.Value) {
var array = [literalOrValueOrArray];
this._dictionaryOfAttributeValues[attributeId] = array;
return array; // Array
}
if (dojo.lang.isArray(literalOrValueOrArray)) {
return literalOrValueOrArray; // Array
}
var literal = literalOrValueOrArray;
var dojoDataValue = new dojo.data.Value(literal);
array = [dojoDataValue];
this._dictionaryOfAttributeValues[attributeId] = array;
return array; // Array
};
dojo.data.Item.prototype.load = function(/* string or dojo.data.Attribute */ attributeId, /* anything */ value) {
/**
* summary:
* Used for loading an attribute value into an item when
* the item is first being loaded into memory from some
* data store (such as a file).
*/
// dojo.lang.assertType(attributeId, [String, dojo.data.Attribute]);
this._dataProvider.registerAttribute(attributeId);
var literalOrValueOrArray = this._dictionaryOfAttributeValues[attributeId];
if (dojo.lang.isUndefined(literalOrValueOrArray)) {
this._dictionaryOfAttributeValues[attributeId] = value;
return;
}
if (!(value instanceof dojo.data.Value)) {
value = new dojo.data.Value(value);
}
if (literalOrValueOrArray instanceof dojo.data.Value) {
var array = [literalOrValueOrArray, value];
this._dictionaryOfAttributeValues[attributeId] = array;
return;
}
if (dojo.lang.isArray(literalOrValueOrArray)) {
literalOrValueOrArray.push(value);
return;
}
var literal = literalOrValueOrArray;
var dojoDataValue = new dojo.data.Value(literal);
array = [dojoDataValue, value];
this._dictionaryOfAttributeValues[attributeId] = array;
};
dojo.data.Item.prototype.set = function(/* string or dojo.data.Attribute */ attributeId, /* anything */ value) {
/**
* summary:
* Used for setting an attribute value as a result of a
* user action.
*/
// dojo.lang.assertType(attributeId, [String, dojo.data.Attribute]);
this._dataProvider.registerAttribute(attributeId);
this._dictionaryOfAttributeValues[attributeId] = value;
this._dataProvider.noteChange(this, attributeId, value);
};
dojo.data.Item.prototype.setValue = function(/* string or dojo.data.Attribute */ attributeId, /* dojo.data.Value */ value) {
this.set(attributeId, value);
};
dojo.data.Item.prototype.addValue = function(/* string or dojo.data.Attribute */ attributeId, /* anything */ value) {
/**
* summary:
* Used for adding an attribute value as a result of a
* user action.
*/
this.load(attributeId, value);
this._dataProvider.noteChange(this, attributeId, value);
};
dojo.data.Item.prototype.setValues = function(/* string or dojo.data.Attribute */ attributeId, /* Array */ arrayOfValues) {
/**
* summary:
* Used for setting an array of attribute values as a result of a
* user action.
*/
// dojo.lang.assertType(attributeId, [String, dojo.data.Attribute]);
dojo.lang.assertType(arrayOfValues, Array);
this._dataProvider.registerAttribute(attributeId);
var finalArray = [];
this._dictionaryOfAttributeValues[attributeId] = finalArray;
for (var i in arrayOfValues) {
var value = arrayOfValues[i];
if (!(value instanceof dojo.data.Value)) {
value = new dojo.data.Value(value);
}
finalArray.push(value);
this._dataProvider.noteChange(this, attributeId, value);
}
};
dojo.data.Item.prototype.getAttributes = function() {
/**
* summary:
* Returns an array containing all of the attributes for which
* this item has attribute values.
*/
var arrayOfAttributes = [];
for (var key in this._dictionaryOfAttributeValues) {
arrayOfAttributes.push(this._dataProvider.getAttribute(key));
}
return arrayOfAttributes; // Array
};
dojo.data.Item.prototype.hasAttribute = function(/* string or dojo.data.Attribute */ attributeId) {
/**
* summary: Returns true if the given attribute of the item has been assigned any value.
*/
// dojo.lang.assertType(attributeId, [String, dojo.data.Attribute]);
for (var key in this._dictionaryOfAttributeValues) {
if (key == attributeId) {
return true; // boolean
}
}
return false; // boolean
};
dojo.data.Item.prototype.hasAttributeValue = function(/* string or dojo.data.Attribute */ attributeId, /* anything */ value) {
/**
* summary: Returns true if the given attribute of the item has been assigned the given value.
*/
var arrayOfValues = this.getValues(attributeId);
for (var i in arrayOfValues) {
var candidateValue = arrayOfValues[i];
if (candidateValue.isEqual(value)) {
return true; // boolean
}
}
return false; // boolean
};

View file

@ -0,0 +1,28 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Kind");
dojo.require("dojo.data.Item");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.Kind = function(/* dojo.data.provider.Base */ dataProvider) {
/**
* summary:
* A Kind represents a kind of item. In the dojo data model
* the item Snoopy might belong to the 'kind' Dog, where in
* a Java program the object Snoopy would belong to the 'class'
* Dog, and in MySQL the record for Snoopy would be in the
* table Dog.
*/
dojo.data.Item.call(this, dataProvider);
};
dojo.inherits(dojo.data.Kind, dojo.data.Item);

View file

@ -0,0 +1,59 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Observable");
dojo.require("dojo.lang.common");
dojo.require("dojo.lang.assert");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.Observable = function() {
};
// -------------------------------------------------------------------
// Public instance methods
// -------------------------------------------------------------------
dojo.data.Observable.prototype.addObserver = function(/* object */ observer) {
/**
* summary: Registers an object as an observer of this item,
* so that the object will be notified when the item changes.
*/
dojo.lang.assertType(observer, Object);
dojo.lang.assertType(observer.observedObjectHasChanged, Function);
if (!this._arrayOfObservers) {
this._arrayOfObservers = [];
}
if (!dojo.lang.inArray(this._arrayOfObservers, observer)) {
this._arrayOfObservers.push(observer);
}
};
dojo.data.Observable.prototype.removeObserver = function(/* object */ observer) {
/**
* summary: Removes the observer registration for a previously
* registered object.
*/
if (!this._arrayOfObservers) {
return;
}
var index = dojo.lang.indexOf(this._arrayOfObservers, observer);
if (index != -1) {
this._arrayOfObservers.splice(index, 1);
}
};
dojo.data.Observable.prototype.getObservers = function() {
/**
* summary: Returns an array with all the observers of this item.
*/
return this._arrayOfObservers; // Array or undefined
};

View file

@ -0,0 +1,70 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.ResultSet");
dojo.require("dojo.lang.assert");
dojo.require("dojo.collections.Collections");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.ResultSet = function(/* dojo.data.provider.Base */ dataProvider, /* Array */ arrayOfItems) {
/**
* summary:
* A ResultSet holds a collection of Items. A data provider
* returns a ResultSet in reponse to a query.
* (The name "Result Set" comes from the MySQL terminology.)
*/
dojo.lang.assertType(dataProvider, [dojo.data.provider.Base, "optional"]);
dojo.lang.assertType(arrayOfItems, [Array, "optional"]);
dojo.data.Observable.call(this);
this._dataProvider = dataProvider;
this._arrayOfItems = [];
if (arrayOfItems) {
this._arrayOfItems = arrayOfItems;
}
};
dojo.inherits(dojo.data.ResultSet, dojo.data.Observable);
// -------------------------------------------------------------------
// Public instance methods
// -------------------------------------------------------------------
dojo.data.ResultSet.prototype.toString = function() {
var returnString = this._arrayOfItems.join(', ');
return returnString; // string
};
dojo.data.ResultSet.prototype.toArray = function() {
return this._arrayOfItems; // Array
};
dojo.data.ResultSet.prototype.getIterator = function() {
return new dojo.collections.Iterator(this._arrayOfItems);
};
dojo.data.ResultSet.prototype.getLength = function() {
return this._arrayOfItems.length; // integer
};
dojo.data.ResultSet.prototype.getItemAt = function(/* numeric */ index) {
return this._arrayOfItems[index];
};
dojo.data.ResultSet.prototype.indexOf = function(/* dojo.data.Item */ item) {
return dojo.lang.indexOf(this._arrayOfItems, item); // integer
};
dojo.data.ResultSet.prototype.contains = function(/* dojo.data.Item */ item) {
return dojo.lang.inArray(this._arrayOfItems, item); // boolean
};
dojo.data.ResultSet.prototype.getDataProvider = function() {
return this._dataProvider; // dojo.data.provider.Base
};

View file

@ -0,0 +1,25 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Type");
dojo.require("dojo.data.Item");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.Type = function(/* dojo.data.provider.Base */ dataProvider) {
/**
* summary:
* A Type represents a type of value, like Text, Number, Picture,
* or Varchar.
*/
dojo.data.Item.call(this, dataProvider);
};
dojo.inherits(dojo.data.Type, dojo.data.Item);

View file

@ -0,0 +1,55 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Value");
dojo.require("dojo.lang.assert");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.Value = function(/* anything */ value) {
/**
* summary:
* A Value represents a simple literal value (like "foo" or 334),
* or a reference value (a pointer to an Item).
*/
this._value = value;
this._type = null;
};
// -------------------------------------------------------------------
// Public instance methods
// -------------------------------------------------------------------
dojo.data.Value.prototype.toString = function() {
return this._value.toString(); // string
};
dojo.data.Value.prototype.getValue = function() {
/**
* summary: Returns the value itself.
*/
return this._value; // anything
};
dojo.data.Value.prototype.getType = function() {
/**
* summary: Returns the data type of the value.
*/
dojo.unimplemented('dojo.data.Value.prototype.getType');
return this._type; // dojo.data.Type
};
dojo.data.Value.prototype.compare = function() {
dojo.unimplemented('dojo.data.Value.prototype.compare');
};
dojo.data.Value.prototype.isEqual = function() {
dojo.unimplemented('dojo.data.Value.prototype.isEqual');
};

View file

@ -0,0 +1,22 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.experimental");
dojo.experimental("dojo.data.*");
dojo.kwCompoundRequire({
common: [
"dojo.data.Item",
"dojo.data.ResultSet",
"dojo.data.provider.FlatFile"
]
});
dojo.provide("dojo.data.*");

View file

@ -0,0 +1,112 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.format.Csv");
dojo.require("dojo.lang.assert");
dojo.data.format.Csv = new function() {
// -------------------------------------------------------------------
// Public functions
// -------------------------------------------------------------------
this.getArrayStructureFromCsvFileContents = function(/* string */ csvFileContents) {
/**
* Given a string containing CSV records, this method parses
* the string and returns a data structure containing the parsed
* content. The data structure we return is an array of length
* R, where R is the number of rows (lines) in the CSV data. The
* return array contains one sub-array for each CSV line, and each
* sub-array contains C string values, where C is the number of
* columns in the CSV data.
*
* For example, given this CSV string as input:
* <pre>
* "Title, Year, Producer \n Alien, 1979, Ridley Scott \n Blade Runner, 1982, Ridley Scott"
* </pre>
* We will return this data structure:
* <pre>
* [["Title", "Year", "Producer"]
* ["Alien", "1979", "Ridley Scott"],
* ["Blade Runner", "1982", "Ridley Scott"]]
* </pre>
*/
dojo.lang.assertType(csvFileContents, String);
var lineEndingCharacters = new RegExp("\r\n|\n|\r");
var leadingWhiteSpaceCharacters = new RegExp("^\\s+",'g');
var trailingWhiteSpaceCharacters = new RegExp("\\s+$",'g');
var doubleQuotes = new RegExp('""','g');
var arrayOfOutputRecords = [];
var arrayOfInputLines = csvFileContents.split(lineEndingCharacters);
for (var i in arrayOfInputLines) {
var singleLine = arrayOfInputLines[i];
if (singleLine.length > 0) {
var listOfFields = singleLine.split(',');
var j = 0;
while (j < listOfFields.length) {
var space_field_space = listOfFields[j];
var field_space = space_field_space.replace(leadingWhiteSpaceCharacters, ''); // trim leading whitespace
var field = field_space.replace(trailingWhiteSpaceCharacters, ''); // trim trailing whitespace
var firstChar = field.charAt(0);
var lastChar = field.charAt(field.length - 1);
var secondToLastChar = field.charAt(field.length - 2);
var thirdToLastChar = field.charAt(field.length - 3);
if ((firstChar == '"') &&
((lastChar != '"') ||
((lastChar == '"') && (secondToLastChar == '"') && (thirdToLastChar != '"')) )) {
if (j+1 === listOfFields.length) {
// alert("The last field in record " + i + " is corrupted:\n" + field);
return null;
}
var nextField = listOfFields[j+1];
listOfFields[j] = field_space + ',' + nextField;
listOfFields.splice(j+1, 1); // delete element [j+1] from the list
} else {
if ((firstChar == '"') && (lastChar == '"')) {
field = field.slice(1, (field.length - 1)); // trim the " characters off the ends
field = field.replace(doubleQuotes, '"'); // replace "" with "
}
listOfFields[j] = field;
j += 1;
}
}
arrayOfOutputRecords.push(listOfFields);
}
}
return arrayOfOutputRecords; // Array
};
this.loadDataProviderFromFileContents = function(/* dojo.data.provider.Base */ dataProvider, /* string */ csvFileContents) {
dojo.lang.assertType(dataProvider, dojo.data.provider.Base);
dojo.lang.assertType(csvFileContents, String);
var arrayOfArrays = this.getArrayStructureFromCsvFileContents(csvFileContents);
if (arrayOfArrays) {
var arrayOfKeys = arrayOfArrays[0];
for (var i = 1; i < arrayOfArrays.length; ++i) {
var row = arrayOfArrays[i];
var item = dataProvider.getNewItemToLoad();
for (var j in row) {
var value = row[j];
var key = arrayOfKeys[j];
item.load(key, value);
}
}
}
};
this.getCsvStringFromResultSet = function(/* dojo.data.ResultSet */ resultSet) {
dojo.unimplemented('dojo.data.format.Csv.getCsvStringFromResultSet');
var csvString = null;
return csvString; // String
};
}();

View file

@ -0,0 +1,103 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.format.Json");
dojo.require("dojo.lang.assert");
dojo.data.format.Json = new function() {
// -------------------------------------------------------------------
// Public functions
// -------------------------------------------------------------------
this.loadDataProviderFromFileContents = function(/* dojo.data.provider.Base */ dataProvider, /* string */ jsonFileContents) {
dojo.lang.assertType(dataProvider, dojo.data.provider.Base);
dojo.lang.assertType(jsonFileContents, String);
var arrayOfJsonData = eval("(" + jsonFileContents + ")");
this.loadDataProviderFromArrayOfJsonData(dataProvider, arrayOfJsonData);
};
this.loadDataProviderFromArrayOfJsonData = function(/* dojo.data.provider.Base */ dataProvider, /* Array */ arrayOfJsonData) {
dojo.lang.assertType(arrayOfJsonData, [Array, "optional"]);
if (arrayOfJsonData && (arrayOfJsonData.length > 0)) {
var firstRow = arrayOfJsonData[0];
dojo.lang.assertType(firstRow, [Array, "pureobject"]);
if (dojo.lang.isArray(firstRow)) {
_loadDataProviderFromArrayOfArrays(dataProvider, arrayOfJsonData);
} else {
dojo.lang.assertType(firstRow, "pureobject");
_loadDataProviderFromArrayOfObjects(dataProvider, arrayOfJsonData);
}
}
};
this.getJsonStringFromResultSet = function(/* dojo.data.ResultSet */ resultSet) {
dojo.unimplemented('dojo.data.format.Json.getJsonStringFromResultSet');
var jsonString = null;
return jsonString; // String
};
// -------------------------------------------------------------------
// Private functions
// -------------------------------------------------------------------
function _loadDataProviderFromArrayOfArrays(/* dojo.data.provider.Base */ dataProvider, /* Array */ arrayOfJsonData) {
/**
* Example:
* var arrayOfJsonStates = [
* [ "abbr", "population", "name" ]
* [ "WA", 5894121, "Washington" ],
* [ "WV", 1808344, "West Virginia" ],
* [ "WI", 5453896, "Wisconsin" ],
* [ "WY", 493782, "Wyoming" ] ];
* this._loadFromArrayOfArrays(arrayOfJsonStates);
*/
var arrayOfKeys = arrayOfJsonData[0];
for (var i = 1; i < arrayOfJsonData.length; ++i) {
var row = arrayOfJsonData[i];
var item = dataProvider.getNewItemToLoad();
for (var j in row) {
var value = row[j];
var key = arrayOfKeys[j];
item.load(key, value);
}
}
}
function _loadDataProviderFromArrayOfObjects(/* dojo.data.provider.Base */ dataProvider, /* Array */ arrayOfJsonData) {
/**
* Example:
* var arrayOfJsonStates = [
* { abbr: "WA", name: "Washington" },
* { abbr: "WV", name: "West Virginia" },
* { abbr: "WI", name: "Wisconsin", song: "On, Wisconsin!" },
* { abbr: "WY", name: "Wyoming", cities: ["Lander", "Cheyenne", "Laramie"] } ];
* this._loadFromArrayOfArrays(arrayOfJsonStates);
*/
// dojo.debug("_loadDataProviderFromArrayOfObjects");
for (var i in arrayOfJsonData) {
var row = arrayOfJsonData[i];
var item = dataProvider.getNewItemToLoad();
for (var key in row) {
var value = row[key];
if (dojo.lang.isArray(value)) {
var arrayOfValues = value;
for (var j in arrayOfValues) {
value = arrayOfValues[j];
item.load(key, value);
// dojo.debug("loaded: " + key + " = " + value);
}
} else {
item.load(key, value);
}
}
}
}
}();

View file

@ -0,0 +1,183 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.provider.Base");
dojo.require("dojo.lang.assert");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.provider.Base = function() {
/**
* summary:
* A Data Provider serves as a connection to some data source,
* like a relational database. This data provider Base class
* serves as an abstract superclass for other data provider
* classes.
*/
this._countOfNestedTransactions = 0;
this._changesInCurrentTransaction = null;
};
// -------------------------------------------------------------------
// Public instance methods
// -------------------------------------------------------------------
dojo.data.provider.Base.prototype.beginTransaction = function() {
/**
* Marks the beginning of a transaction.
*
* Each time you call beginTransaction() you open a new transaction,
* which you need to close later using endTransaction(). Transactions
* may be nested, but the beginTransaction and endTransaction calls
* always need to come in pairs.
*/
if (this._countOfNestedTransactions === 0) {
this._changesInCurrentTransaction = [];
}
this._countOfNestedTransactions += 1;
};
dojo.data.provider.Base.prototype.endTransaction = function() {
/**
* Marks the end of a transaction.
*/
this._countOfNestedTransactions -= 1;
dojo.lang.assert(this._countOfNestedTransactions >= 0);
if (this._countOfNestedTransactions === 0) {
var listOfChangesMade = this._saveChanges();
this._changesInCurrentTransaction = null;
if (listOfChangesMade.length > 0) {
// dojo.debug("endTransaction: " + listOfChangesMade.length + " changes made");
this._notifyObserversOfChanges(listOfChangesMade);
}
}
};
dojo.data.provider.Base.prototype.getNewItemToLoad = function() {
return this._newItem(); // dojo.data.Item
};
dojo.data.provider.Base.prototype.newItem = function(/* string */ itemName) {
/**
* Creates a new item.
*/
dojo.lang.assertType(itemName, [String, "optional"]);
var item = this._newItem();
if (itemName) {
item.set('name', itemName);
}
return item; // dojo.data.Item
};
dojo.data.provider.Base.prototype.newAttribute = function(/* string */ attributeId) {
/**
* Creates a new attribute.
*/
dojo.lang.assertType(attributeId, String); // FIXME: should be optional
var attribute = this._newAttribute(attributeId);
return attribute; // dojo.data.Attribute
};
dojo.data.provider.Base.prototype.getAttribute = function(/* string */ attributeId) {
dojo.unimplemented('dojo.data.provider.Base');
var attribute;
return attribute; // dojo.data.Attribute
};
dojo.data.provider.Base.prototype.getAttributes = function() {
dojo.unimplemented('dojo.data.provider.Base');
return this._arrayOfAttributes; // Array
};
dojo.data.provider.Base.prototype.fetchArray = function() {
dojo.unimplemented('dojo.data.provider.Base');
return []; // Array
};
dojo.data.provider.Base.prototype.fetchResultSet = function() {
dojo.unimplemented('dojo.data.provider.Base');
var resultSet;
return resultSet; // dojo.data.ResultSet
};
dojo.data.provider.Base.prototype.noteChange = function(/* dojo.data.Item */ item, /* string or dojo.data.Attribute */ attribute, /* anything */ value) {
var change = {item: item, attribute: attribute, value: value};
if (this._countOfNestedTransactions === 0) {
this.beginTransaction();
this._changesInCurrentTransaction.push(change);
this.endTransaction();
} else {
this._changesInCurrentTransaction.push(change);
}
};
dojo.data.provider.Base.prototype.addItemObserver = function(/* dojo.data.Item */ item, /* object */ observer) {
/**
* summary: Registers an object as an observer of an item,
* so that the object will be notified when the item changes.
*/
dojo.lang.assertType(item, dojo.data.Item);
item.addObserver(observer);
};
dojo.data.provider.Base.prototype.removeItemObserver = function(/* dojo.data.Item */ item, /* object */ observer) {
/**
* summary: Removes the observer registration for a previously
* registered object.
*/
dojo.lang.assertType(item, dojo.data.Item);
item.removeObserver(observer);
};
// -------------------------------------------------------------------
// Private instance methods
// -------------------------------------------------------------------
dojo.data.provider.Base.prototype._newItem = function() {
var item = new dojo.data.Item(this);
return item; // dojo.data.Item
};
dojo.data.provider.Base.prototype._newAttribute = function(/* String */ attributeId) {
var attribute = new dojo.data.Attribute(this);
return attribute; // dojo.data.Attribute
};
dojo.data.provider.Base.prototype._saveChanges = function() {
var arrayOfChangesMade = this._changesInCurrentTransaction;
return arrayOfChangesMade; // Array
};
dojo.data.provider.Base.prototype._notifyObserversOfChanges = function(/* Array */ arrayOfChanges) {
var arrayOfResultSets = this._getResultSets();
for (var i in arrayOfChanges) {
var change = arrayOfChanges[i];
var changedItem = change.item;
var arrayOfItemObservers = changedItem.getObservers();
for (var j in arrayOfItemObservers) {
var observer = arrayOfItemObservers[j];
observer.observedObjectHasChanged(changedItem, change);
}
for (var k in arrayOfResultSets) {
var resultSet = arrayOfResultSets[k];
var arrayOfResultSetObservers = resultSet.getObservers();
for (var m in arrayOfResultSetObservers) {
observer = arrayOfResultSetObservers[m];
observer.observedObjectHasChanged(resultSet, change);
}
}
}
};
dojo.data.provider.Base.prototype._getResultSets = function() {
dojo.unimplemented('dojo.data.provider.Base');
return []; // Array
};

View file

@ -0,0 +1,85 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.provider.Delicious");
dojo.require("dojo.data.provider.FlatFile");
dojo.require("dojo.data.format.Json");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.provider.Delicious = function() {
/**
* summary:
* The Delicious Data Provider can be used to take data from
* del.icio.us and make it available as dojo.data.Items
* In order to use the Delicious Data Provider, you need
* to have loaded a script tag that looks like this:
* <script type="text/javascript" src="http://del.icio.us/feeds/json/gumption?count=8"></script>
*/
dojo.data.provider.FlatFile.call(this);
// Delicious = null;
if (Delicious && Delicious.posts) {
dojo.data.format.Json.loadDataProviderFromArrayOfJsonData(this, Delicious.posts);
} else {
// document.write("<script type='text/javascript'>dojo.data.provider.Delicious._fetchComplete()</script>");
/*
document.write("<script type='text/javascript'>alert('boo!');</script>");
document.write("<script type='text/javascript'>var foo = 'not dojo'; alert('dojo == ' + foo);</script>");
document.write("<script type='text/javascript'>var foo = fetchComplete; alert('dojo == ' + foo);</script>");
fetchComplete();
*/
// dojo.debug("Delicious line 29: constructor");
}
var u = this.registerAttribute('u');
var d = this.registerAttribute('d');
var t = this.registerAttribute('t');
u.load('name', 'Bookmark');
d.load('name', 'Description');
t.load('name', 'Tags');
u.load('type', 'String');
d.load('type', 'String');
t.load('type', 'String');
};
dojo.inherits(dojo.data.provider.Delicious, dojo.data.provider.FlatFile);
/********************************************************************
* FIXME: the rest of this is work in progress
*
dojo.data.provider.Delicious.prototype.getNewItemToLoad = function() {
var newItem = this._newItem();
this._currentArray.push(newItem);
return newItem; // dojo.data.Item
};
dojo.data.provider.Delicious.prototype.fetchArray = function(query) {
if (!query) {
query = "gumption";
}
this._currentArray = [];
alert("Delicious line 60: loadDataProviderFromArrayOfJsonData");
alert("Delicious line 61: " + dojo);
var sourceUrl = "http://del.icio.us/feeds/json/" + query + "?count=8";
document.write("<script type='text/javascript' src='" + sourceUrl + "'></script>");
document.write("<script type='text/javascript'>alert('line 63: ' + Delicious.posts[0].u);</script>");
document.write("<script type='text/javascript'>callMe();</script>");
alert("line 66");
dojo.data.format.Json.loadDataProviderFromArrayOfJsonData(this, Delicious.posts);
return this._currentArray; // Array
};
callMe = function() {
alert("callMe!");
};
*/

View file

@ -0,0 +1,153 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.provider.FlatFile");
dojo.require("dojo.data.provider.Base");
dojo.require("dojo.data.Item");
dojo.require("dojo.data.Attribute");
dojo.require("dojo.data.ResultSet");
dojo.require("dojo.data.format.Json");
dojo.require("dojo.data.format.Csv");
dojo.require("dojo.lang.assert");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.provider.FlatFile = function(/* keywords */ keywordParameters) {
/**
* summary:
* A Json Data Provider knows how to read in simple JSON data
* tables and make their contents accessable as Items.
*/
dojo.lang.assertType(keywordParameters, ["pureobject", "optional"]);
dojo.data.provider.Base.call(this);
this._arrayOfItems = [];
this._resultSet = null;
this._dictionaryOfAttributes = {};
if (keywordParameters) {
var jsonObjects = keywordParameters["jsonObjects"];
var jsonString = keywordParameters["jsonString"];
var fileUrl = keywordParameters["url"];
if (jsonObjects) {
dojo.data.format.Json.loadDataProviderFromArrayOfJsonData(this, jsonObjects);
}
if (jsonString) {
dojo.data.format.Json.loadDataProviderFromFileContents(this, jsonString);
}
if (fileUrl) {
var arrayOfParts = fileUrl.split('.');
var lastPart = arrayOfParts[(arrayOfParts.length - 1)];
var formatParser = null;
if (lastPart == "json") {
formatParser = dojo.data.format.Json;
}
if (lastPart == "csv") {
formatParser = dojo.data.format.Csv;
}
if (formatParser) {
var fileContents = dojo.hostenv.getText(fileUrl);
formatParser.loadDataProviderFromFileContents(this, fileContents);
} else {
dojo.lang.assert(false, "new dojo.data.provider.FlatFile({url: }) was passed a file without a .csv or .json suffix");
}
}
}
};
dojo.inherits(dojo.data.provider.FlatFile, dojo.data.provider.Base);
// -------------------------------------------------------------------
// Public instance methods
// -------------------------------------------------------------------
dojo.data.provider.FlatFile.prototype.getProviderCapabilities = function(/* string */ keyword) {
dojo.lang.assertType(keyword, [String, "optional"]);
if (!this._ourCapabilities) {
this._ourCapabilities = {
transactions: false,
undo: false,
login: false,
versioning: false,
anonymousRead: true,
anonymousWrite: false,
permissions: false,
queries: false,
strongTyping: false,
datatypes: [String, Date, Number]
};
}
if (keyword) {
return this._ourCapabilities[keyword];
} else {
return this._ourCapabilities;
}
};
dojo.data.provider.FlatFile.prototype.registerAttribute = function(/* string or dojo.data.Attribute */ attributeId) {
var registeredAttribute = this.getAttribute(attributeId);
if (!registeredAttribute) {
var newAttribute = new dojo.data.Attribute(this, attributeId);
this._dictionaryOfAttributes[attributeId] = newAttribute;
registeredAttribute = newAttribute;
}
return registeredAttribute; // dojo.data.Attribute
};
dojo.data.provider.FlatFile.prototype.getAttribute = function(/* string or dojo.data.Attribute */ attributeId) {
var attribute = (this._dictionaryOfAttributes[attributeId] || null);
return attribute; // dojo.data.Attribute or null
};
dojo.data.provider.FlatFile.prototype.getAttributes = function() {
var arrayOfAttributes = [];
for (var key in this._dictionaryOfAttributes) {
var attribute = this._dictionaryOfAttributes[key];
arrayOfAttributes.push(attribute);
}
return arrayOfAttributes; // Array
};
dojo.data.provider.FlatFile.prototype.fetchArray = function(query) {
/**
* summary: Returns an Array containing all of the Items.
*/
return this._arrayOfItems; // Array
};
dojo.data.provider.FlatFile.prototype.fetchResultSet = function(query) {
/**
* summary: Returns a ResultSet containing all of the Items.
*/
if (!this._resultSet) {
this._resultSet = new dojo.data.ResultSet(this, this.fetchArray(query));
}
return this._resultSet; // dojo.data.ResultSet
};
// -------------------------------------------------------------------
// Private instance methods
// -------------------------------------------------------------------
dojo.data.provider.FlatFile.prototype._newItem = function() {
var item = new dojo.data.Item(this);
this._arrayOfItems.push(item);
return item; // dojo.data.Item
};
dojo.data.provider.FlatFile.prototype._newAttribute = function(/* String */ attributeId) {
dojo.lang.assertType(attributeId, String);
dojo.lang.assert(this.getAttribute(attributeId) === null);
var attribute = new dojo.data.Attribute(this, attributeId);
this._dictionaryOfAttributes[attributeId] = attribute;
return attribute; // dojo.data.Attribute
};
dojo.data.provider.Base.prototype._getResultSets = function() {
return [this._resultSet]; // Array
};

View file

@ -0,0 +1,27 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.provider.JotSpot");
dojo.require("dojo.data.provider.Base");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.provider.JotSpot = function() {
/**
* summary:
* A JotSpot Data Provider knows how to read data from a JotSpot data
* store and make the contents accessable as dojo.data.Items.
*/
dojo.unimplemented('dojo.data.provider.JotSpot');
};
dojo.inherits(dojo.data.provider.JotSpot, dojo.data.provider.Base);

View file

@ -0,0 +1,27 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.provider.MySql");
dojo.require("dojo.data.provider.Base");
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
dojo.data.provider.MySql = function() {
/**
* summary:
* A MySql Data Provider knows how to connect to a MySQL database
* on a server and and make the content records available as
* dojo.data.Items.
*/
dojo.unimplemented('dojo.data.provider.MySql');
};
dojo.inherits(dojo.data.provider.MySql, dojo.data.provider.Base);

View file

@ -0,0 +1,45 @@
Existing Features
* can import data from .json or .csv format files
* can import data from del.icio.us
* can create and modify data programmatically
* can bind data to dojo.widget.Chart
* can bind data to dojo.widget.SortableTable
* can bind one data set to multiple widgets
* notifications: widgets are notified when data changes
* notification available per-item or per-resultSet
* can create ad-hoc attributes
* attributes can be loosely-typed
* attributes can have meta-data like type and display name
* half-implemented support for sorting
* half-implemented support for export to .json
* API for getting data in simple arrays
* API for getting ResultSets with iterators (precursor to support for something like the openrico.org live grid)
~~~~~~~~~~~~~~~~~~~~~~~~
To-Do List
* be able to import data from an html <table></table>
* think about being able to import data from some type of XML
* think about integration with dojo.undo.Manager
* think more about how to represent the notion of different data types
* think about what problems we'll run into when we have a MySQL data provider
* in TableBindingHack, improve support for data types in the SortableTable binding
* deal with ids (including MySQL multi-field keys)
* add support for item-references: employeeItem.set('department', departmentItem);
* deal with Attributes as instances of Items, not just subclasses of Items
* unit tests for compare/sort code
* unit tests for everything
* implement item.toString('json') and item.toString('xml')
* implement dataProvider.newItem({name: 'foo', age: 26})
* deal better with transactions
* add support for deleting items
* don't send out multiple notifications to the same observer
* deal with item versions
* prototype a Yahoo data provider -- http://developer.yahoo.net/common/json.html
* prototype a data provider that enforces strong typing
* prototype a data provider that prevents ad-hoc attributes
* prototype a data provider that enforces single-kind item
* prototype a data provider that allows for login/authentication
* have loosely typed result sets play nicely with widgets that expect strong typing
* prototype an example of spreadsheet-style formulas or derivation rules
* experiment with some sort of fetch() that returns only a subset of a data provider's items

761
webapp/web/src/date.js Normal file
View file

@ -0,0 +1,761 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.date");
/* Supplementary Date Functions
*******************************/
dojo.date.setDayOfYear = function (dateObject, dayofyear) {
dateObject.setMonth(0);
dateObject.setDate(dayofyear);
return dateObject;
}
dojo.date.getDayOfYear = function (dateObject) {
var firstDayOfYear = new Date(dateObject.getFullYear(), 0, 1);
return Math.floor((dateObject.getTime() -
firstDayOfYear.getTime()) / 86400000);
}
dojo.date.setWeekOfYear = function (dateObject, week, firstDay) {
if (arguments.length == 1) { firstDay = 0; } // Sunday
dojo.unimplemented("dojo.date.setWeekOfYear");
}
dojo.date.getWeekOfYear = function (dateObject, firstDay) {
if (arguments.length == 1) { firstDay = 0; } // Sunday
// work out the first day of the year corresponding to the week
var firstDayOfYear = new Date(dateObject.getFullYear(), 0, 1);
var day = firstDayOfYear.getDay();
firstDayOfYear.setDate(firstDayOfYear.getDate() -
day + firstDay - (day > firstDay ? 7 : 0));
return Math.floor((dateObject.getTime() -
firstDayOfYear.getTime()) / 604800000);
}
dojo.date.setIsoWeekOfYear = function (dateObject, week, firstDay) {
if (arguments.length == 1) { firstDay = 1; } // Monday
dojo.unimplemented("dojo.date.setIsoWeekOfYear");
}
dojo.date.getIsoWeekOfYear = function (dateObject, firstDay) {
if (arguments.length == 1) { firstDay = 1; } // Monday
dojo.unimplemented("dojo.date.getIsoWeekOfYear");
}
/* ISO 8601 Functions
*********************/
dojo.date.setIso8601 = function (dateObject, string){
var comps = (string.indexOf("T") == -1) ? string.split(" ") : string.split("T");
dojo.date.setIso8601Date(dateObject, comps[0]);
if (comps.length == 2) { dojo.date.setIso8601Time(dateObject, comps[1]); }
return dateObject;
}
dojo.date.fromIso8601 = function (string) {
return dojo.date.setIso8601(new Date(0, 0), string);
}
dojo.date.setIso8601Date = function (dateObject, string) {
var regexp = "^([0-9]{4})((-?([0-9]{2})(-?([0-9]{2}))?)|" +
"(-?([0-9]{3}))|(-?W([0-9]{2})(-?([1-7]))?))?$";
var d = string.match(new RegExp(regexp));
if(!d) {
dojo.debug("invalid date string: " + string);
return false;
}
var year = d[1];
var month = d[4];
var date = d[6];
var dayofyear = d[8];
var week = d[10];
var dayofweek = (d[12]) ? d[12] : 1;
dateObject.setYear(year);
if (dayofyear) { dojo.date.setDayOfYear(dateObject, Number(dayofyear)); }
else if (week) {
dateObject.setMonth(0);
dateObject.setDate(1);
var gd = dateObject.getDay();
var day = (gd) ? gd : 7;
var offset = Number(dayofweek) + (7 * Number(week));
if (day <= 4) { dateObject.setDate(offset + 1 - day); }
else { dateObject.setDate(offset + 8 - day); }
} else {
if (month) {
dateObject.setDate(1);
dateObject.setMonth(month - 1);
}
if (date) { dateObject.setDate(date); }
}
return dateObject;
}
dojo.date.fromIso8601Date = function (string) {
return dojo.date.setIso8601Date(new Date(0, 0), string);
}
dojo.date.setIso8601Time = function (dateObject, string) {
// first strip timezone info from the end
var timezone = "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$";
var d = string.match(new RegExp(timezone));
var offset = 0; // local time if no tz info
if (d) {
if (d[0] != 'Z') {
offset = (Number(d[3]) * 60) + Number(d[5]);
offset *= ((d[2] == '-') ? 1 : -1);
}
offset -= dateObject.getTimezoneOffset();
string = string.substr(0, string.length - d[0].length);
}
// then work out the time
var regexp = "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$";
var d = string.match(new RegExp(regexp));
if(!d) {
dojo.debug("invalid time string: " + string);
return false;
}
var hours = d[1];
var mins = Number((d[3]) ? d[3] : 0);
var secs = (d[5]) ? d[5] : 0;
var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0;
dateObject.setHours(hours);
dateObject.setMinutes(mins);
dateObject.setSeconds(secs);
dateObject.setMilliseconds(ms);
return dateObject;
}
dojo.date.fromIso8601Time = function (string) {
return dojo.date.setIso8601Time(new Date(0, 0), string);
}
/* Informational Functions
**************************/
dojo.date.shortTimezones = ["IDLW", "BET", "HST", "MART", "AKST", "PST", "MST",
"CST", "EST", "AST", "NFT", "BST", "FST", "AT", "GMT", "CET", "EET", "MSK",
"IRT", "GST", "AFT", "AGTT", "IST", "NPT", "ALMT", "MMT", "JT", "AWST",
"JST", "ACST", "AEST", "LHST", "VUT", "NFT", "NZT", "CHAST", "PHOT",
"LINT"];
dojo.date.timezoneOffsets = [-720, -660, -600, -570, -540, -480, -420, -360,
-300, -240, -210, -180, -120, -60, 0, 60, 120, 180, 210, 240, 270, 300,
330, 345, 360, 390, 420, 480, 540, 570, 600, 630, 660, 690, 720, 765, 780,
840];
/*
dojo.date.timezones = ["International Date Line West", "Bering Standard Time",
"Hawaiian Standard Time", "Marquesas Time", "Alaska Standard Time",
"Pacific Standard Time (USA)", "Mountain Standard Time",
"Central Standard Time (USA)", "Eastern Standard Time (USA)",
"Atlantic Standard Time", "Newfoundland Time", "Brazil Standard Time",
"Fernando de Noronha Standard Time (Brazil)", "Azores Time",
"Greenwich Mean Time", "Central Europe Time", "Eastern Europe Time",
"Moscow Time", "Iran Standard Time", "Gulf Standard Time",
"Afghanistan Time", "Aqtobe Time", "Indian Standard Time", "Nepal Time",
"Almaty Time", "Myanmar Time", "Java Time",
"Australian Western Standard Time", "Japan Standard Time",
"Australian Central Standard Time", "Lord Hove Standard Time (Australia)",
"Vanuata Time", "Norfolk Time (Australia)", "New Zealand Standard Time",
"Chatham Standard Time (New Zealand)", "Phoenix Islands Time (Kribati)",
"Line Islands Time (Kribati)"];
*/
dojo.date.months = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
dojo.date.shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "June",
"July", "Aug", "Sep", "Oct", "Nov", "Dec"];
dojo.date.days = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"];
dojo.date.shortDays = ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"];
dojo.date.getDaysInMonth = function (dateObject) {
var month = dateObject.getMonth();
var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if (month == 1 && dojo.date.isLeapYear(dateObject)) { return 29; }
else { return days[month]; }
}
dojo.date.isLeapYear = function (dateObject) {
/*
* Leap years are years with an additional day YYYY-02-29, where the year
* number is a multiple of four with the following exception: If a year
* is a multiple of 100, then it is only a leap year if it is also a
* multiple of 400. For example, 1900 was not a leap year, but 2000 is one.
*/
var year = dateObject.getFullYear();
return (year%400 == 0) ? true : (year%100 == 0) ? false : (year%4 == 0) ? true : false;
}
dojo.date.getDayName = function (dateObject) {
return dojo.date.days[dateObject.getDay()];
}
dojo.date.getDayShortName = function (dateObject) {
return dojo.date.shortDays[dateObject.getDay()];
}
dojo.date.getMonthName = function (dateObject) {
return dojo.date.months[dateObject.getMonth()];
}
dojo.date.getMonthShortName = function (dateObject) {
return dojo.date.shortMonths[dateObject.getMonth()];
}
dojo.date.getTimezoneName = function (dateObject) {
// need to negate timezones to get it right
// i.e UTC+1 is CET winter, but getTimezoneOffset returns -60
var timezoneOffset = -(dateObject.getTimezoneOffset());
for (var i = 0; i < dojo.date.timezoneOffsets.length; i++) {
if (dojo.date.timezoneOffsets[i] == timezoneOffset) {
return dojo.date.shortTimezones[i];
}
}
// we don't know so return it formatted as "+HH:MM"
function $ (s) { s = String(s); while (s.length < 2) { s = "0" + s; } return s; }
return (timezoneOffset < 0 ? "-" : "+") + $(Math.floor(Math.abs(
timezoneOffset)/60)) + ":" + $(Math.abs(timezoneOffset)%60);
}
dojo.date.getOrdinal = function (dateObject) {
var date = dateObject.getDate();
if (date%100 != 11 && date%10 == 1) { return "st"; }
else if (date%100 != 12 && date%10 == 2) { return "nd"; }
else if (date%100 != 13 && date%10 == 3) { return "rd"; }
else { return "th"; }
}
/* Date Formatter Functions
***************************/
// POSIX strftime
// see <http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html>
dojo.date.format = dojo.date.strftime = function (dateObject, format) {
// zero pad
var padChar = null;
function _ (s, n) {
s = String(s);
n = (n || 2) - s.length;
while (n-- > 0) { s = (padChar == null ? "0" : padChar) + s; }
return s;
}
function $ (property) {
switch (property) {
case "a": // abbreviated weekday name according to the current locale
return dojo.date.getDayShortName(dateObject); break;
case "A": // full weekday name according to the current locale
return dojo.date.getDayName(dateObject); break;
case "b":
case "h": // abbreviated month name according to the current locale
return dojo.date.getMonthShortName(dateObject); break;
case "B": // full month name according to the current locale
return dojo.date.getMonthName(dateObject); break;
case "c": // preferred date and time representation for the current
// locale
return dateObject.toLocaleString(); break;
case "C": // century number (the year divided by 100 and truncated
// to an integer, range 00 to 99)
return _(Math.floor(dateObject.getFullYear()/100)); break;
case "d": // day of the month as a decimal number (range 01 to 31)
return _(dateObject.getDate()); break;
case "D": // same as %m/%d/%y
return $("m") + "/" + $("d") + "/" + $("y"); break;
case "e": // day of the month as a decimal number, a single digit is
// preceded by a space (range ' 1' to '31')
if (padChar == null) { padChar = " "; }
return _(dateObject.getDate(), 2); break;
case "g": // like %G, but without the century.
break;
case "G": // The 4-digit year corresponding to the ISO week number
// (see %V). This has the same format and value as %Y,
// except that if the ISO week number belongs to the
// previous or next year, that year is used instead.
break;
case "F": // same as %Y-%m-%d
return $("Y") + "-" + $("m") + "-" + $("d"); break;
case "H": // hour as a decimal number using a 24-hour clock (range
// 00 to 23)
return _(dateObject.getHours()); break;
case "I": // hour as a decimal number using a 12-hour clock (range
// 01 to 12)
return _(dateObject.getHours() % 12 || 12); break;
case "j": // day of the year as a decimal number (range 001 to 366)
return _(dojo.date.getDayOfYear(dateObject), 3); break;
case "m": // month as a decimal number (range 01 to 12)
return _(dateObject.getMonth() + 1); break;
case "M": // minute as a decimal numbe
return _(dateObject.getMinutes()); break;
case "n":
return "\n"; break;
case "p": // either `am' or `pm' according to the given time value,
// or the corresponding strings for the current locale
return dateObject.getHours() < 12 ? "am" : "pm"; break;
case "r": // time in a.m. and p.m. notation
return $("I") + ":" + $("M") + ":" + $("S") + " " + $("p"); break;
case "R": // time in 24 hour notation
return $("H") + ":" + $("M"); break;
case "S": // second as a decimal number
return _(dateObject.getSeconds()); break;
case "t":
return "\t"; break;
case "T": // current time, equal to %H:%M:%S
return $("H") + ":" + $("M") + ":" + $("S"); break;
case "u": // weekday as a decimal number [1,7], with 1 representing
// Monday
return String(dateObject.getDay() || 7); break;
case "U": // week number of the current year as a decimal number,
// starting with the first Sunday as the first day of the
// first week
return _(dojo.date.getWeekOfYear(dateObject)); break;
case "V": // week number of the year (Monday as the first day of the
// week) as a decimal number [01,53]. If the week containing
// 1 January has four or more days in the new year, then it
// is considered week 1. Otherwise, it is the last week of
// the previous year, and the next week is week 1.
return _(dojo.date.getIsoWeekOfYear(dateObject)); break;
case "W": // week number of the current year as a decimal number,
// starting with the first Monday as the first day of the
// first week
return _(dojo.date.getWeekOfYear(dateObject, 1)); break;
case "w": // day of the week as a decimal, Sunday being 0
return String(dateObject.getDay()); break;
case "x": // preferred date representation for the current locale
// without the time
break;
case "X": // preferred date representation for the current locale
// without the time
break;
case "y": // year as a decimal number without a century (range 00 to
// 99)
return _(dateObject.getFullYear()%100); break;
case "Y": // year as a decimal number including the century
return String(dateObject.getFullYear()); break;
case "z": // time zone or name or abbreviation
var timezoneOffset = dateObject.getTimezoneOffset();
return (timezoneOffset < 0 ? "-" : "+") +
_(Math.floor(Math.abs(timezoneOffset)/60)) + ":" +
_(Math.abs(timezoneOffset)%60); break;
case "Z": // time zone or name or abbreviation
return dojo.date.getTimezoneName(dateObject); break;
case "%":
return "%"; break;
}
}
// parse the formatting string and construct the resulting string
var string = "";
var i = 0, index = 0, switchCase;
while ((index = format.indexOf("%", i)) != -1) {
string += format.substring(i, index++);
// inspect modifier flag
switch (format.charAt(index++)) {
case "_": // Pad a numeric result string with spaces.
padChar = " "; break;
case "-": // Do not pad a numeric result string.
padChar = ""; break;
case "0": // Pad a numeric result string with zeros.
padChar = "0"; break;
case "^": // Convert characters in result string to upper case.
switchCase = "upper"; break;
case "#": // Swap the case of the result string.
switchCase = "swap"; break;
default: // no modifer flag so decremenet the index
padChar = null; index--; break;
}
// toggle case if a flag is set
var property = $(format.charAt(index++));
if (switchCase == "upper" ||
(switchCase == "swap" && /[a-z]/.test(property))) {
property = property.toUpperCase();
} else if (switchCase == "swap" && !/[a-z]/.test(property)) {
property = property.toLowerCase();
}
var swicthCase = null;
string += property;
i = index;
}
string += format.substring(i);
return string;
}
/* compare and add
******************/
dojo.date.compareTypes={
// summary
// bitmask for comparison operations.
DATE:1, TIME:2
};
dojo.date.compare=function(/* Date */ dateA, /* Date */ dateB, /* int */ options){
// summary
// Compare two date objects by date, time, or both.
var dA=dateA;
var dB=dateB||new Date();
var now=new Date();
var opt=options||(dojo.date.compareTypes.DATE|dojo.date.compareTypes.TIME);
var d1=new Date(
((opt&dojo.date.compareTypes.DATE)?(dA.getFullYear()):now.getFullYear()),
((opt&dojo.date.compareTypes.DATE)?(dA.getMonth()):now.getMonth()),
((opt&dojo.date.compareTypes.DATE)?(dA.getDate()):now.getDate()),
((opt&dojo.date.compareTypes.TIME)?(dA.getHours()):0),
((opt&dojo.date.compareTypes.TIME)?(dA.getMinutes()):0),
((opt&dojo.date.compareTypes.TIME)?(dA.getSeconds()):0)
);
var d2=new Date(
((opt&dojo.date.compareTypes.DATE)?(dB.getFullYear()):now.getFullYear()),
((opt&dojo.date.compareTypes.DATE)?(dB.getMonth()):now.getMonth()),
((opt&dojo.date.compareTypes.DATE)?(dB.getDate()):now.getDate()),
((opt&dojo.date.compareTypes.TIME)?(dB.getHours()):0),
((opt&dojo.date.compareTypes.TIME)?(dB.getMinutes()):0),
((opt&dojo.date.compareTypes.TIME)?(dB.getSeconds()):0)
);
if(d1.valueOf()>d2.valueOf()){
return 1; // int
}
if(d1.valueOf()<d2.valueOf()){
return -1; // int
}
return 0; // int
}
dojo.date.dateParts={
// summary
// constants for use in dojo.date.add
YEAR:0, MONTH:1, DAY:2, HOUR:3, MINUTE:4, SECOND:5, MILLISECOND:6
};
dojo.date.add=function(/* Date */ d, /* dojo.date.dateParts */ unit, /* int */ amount){
var n=(amount)?amount:1;
var v;
switch(unit){
case dojo.date.dateParts.YEAR:{
v=new Date(d.getFullYear()+n, d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
break;
}
case dojo.date.dateParts.MONTH:{
v=new Date(d.getFullYear(), d.getMonth()+n, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
break;
}
case dojo.date.dateParts.HOUR:{
v=new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours()+n, d.getMinutes(), d.getSeconds(), d.getMilliseconds());
break;
}
case dojo.date.dateParts.MINUTE:{
v=new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes()+n, d.getSeconds(), d.getMilliseconds());
break;
}
case dojo.date.dateParts.SECOND:{
v=new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()+n, d.getMilliseconds());
break;
}
case dojo.date.dateParts.MILLISECOND:{
v=new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()+n);
break;
}
default:{
v=new Date(d.getFullYear(), d.getMonth(), d.getDate()+n, d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
}
};
return v; // Date
};
/* Deprecated
*************/
dojo.date.toString = function(date, format){
dojo.deprecated("dojo.date.toString",
"use dojo.date.format instead", "0.4");
if (format.indexOf("#d") > -1) {
format = format.replace(/#dddd/g, dojo.date.getDayOfWeekName(date));
format = format.replace(/#ddd/g, dojo.date.getShortDayOfWeekName(date));
format = format.replace(/#dd/g, (date.getDate().toString().length==1?"0":"")+date.getDate());
format = format.replace(/#d/g, date.getDate());
}
if (format.indexOf("#M") > -1) {
format = format.replace(/#MMMM/g, dojo.date.getMonthName(date));
format = format.replace(/#MMM/g, dojo.date.getShortMonthName(date));
format = format.replace(/#MM/g, ((date.getMonth()+1).toString().length==1?"0":"")+(date.getMonth()+1));
format = format.replace(/#M/g, date.getMonth() + 1);
}
if (format.indexOf("#y") > -1) {
var fullYear = date.getFullYear().toString();
format = format.replace(/#yyyy/g, fullYear);
format = format.replace(/#yy/g, fullYear.substring(2));
format = format.replace(/#y/g, fullYear.substring(3));
}
// Return if only date needed;
if (format.indexOf("#") == -1) {
return format;
}
if (format.indexOf("#h") > -1) {
var hours = date.getHours();
hours = (hours > 12 ? hours - 12 : (hours == 0) ? 12 : hours);
format = format.replace(/#hh/g, (hours.toString().length==1?"0":"")+hours);
format = format.replace(/#h/g, hours);
}
if (format.indexOf("#H") > -1) {
format = format.replace(/#HH/g, (date.getHours().toString().length==1?"0":"")+date.getHours());
format = format.replace(/#H/g, date.getHours());
}
if (format.indexOf("#m") > -1) {
format = format.replace(/#mm/g, (date.getMinutes().toString().length==1?"0":"")+date.getMinutes());
format = format.replace(/#m/g, date.getMinutes());
}
if (format.indexOf("#s") > -1) {
format = format.replace(/#ss/g, (date.getSeconds().toString().length==1?"0":"")+date.getSeconds());
format = format.replace(/#s/g, date.getSeconds());
}
if (format.indexOf("#T") > -1) {
format = format.replace(/#TT/g, date.getHours() >= 12 ? "PM" : "AM");
format = format.replace(/#T/g, date.getHours() >= 12 ? "P" : "A");
}
if (format.indexOf("#t") > -1) {
format = format.replace(/#tt/g, date.getHours() >= 12 ? "pm" : "am");
format = format.replace(/#t/g, date.getHours() >= 12 ? "p" : "a");
}
return format;
}
dojo.date.daysInMonth = function (month, year) {
dojo.deprecated("daysInMonth(month, year)",
"replaced by getDaysInMonth(dateObject)", "0.4");
return dojo.date.getDaysInMonth(new Date(year, month, 1));
}
/**
*
* Returns a string of the date in the version "January 1, 2004"
*
* @param date The date object
*/
dojo.date.toLongDateString = function(date) {
dojo.deprecated("dojo.date.toLongDateString",
'use dojo.date.format(date, "%B %e, %Y") instead', "0.4");
return dojo.date.format(date, "%B %e, %Y")
}
/**
*
* Returns a string of the date in the version "Jan 1, 2004"
*
* @param date The date object
*/
dojo.date.toShortDateString = function(date) {
dojo.deprecated("dojo.date.toShortDateString",
'use dojo.date.format(date, "%b %e, %Y") instead', "0.4");
return dojo.date.format(date, "%b %e, %Y");
}
/**
*
* Returns military formatted time
*
* @param date the date object
*/
dojo.date.toMilitaryTimeString = function(date){
dojo.deprecated("dojo.date.toMilitaryTimeString",
'use dojo.date.format(date, "%T")', "0.4");
return dojo.date.format(date, "%T");
}
/**
*
* Returns a string of the date relative to the current date.
*
* @param date The date object
*
* Example returns:
* - "1 minute ago"
* - "4 minutes ago"
* - "Yesterday"
* - "2 days ago"
*/
dojo.date.toRelativeString = function(date) {
var now = new Date();
var diff = (now - date) / 1000;
var end = " ago";
var future = false;
if(diff < 0) {
future = true;
end = " from now";
diff = -diff;
}
if(diff < 60) {
diff = Math.round(diff);
return diff + " second" + (diff == 1 ? "" : "s") + end;
} else if(diff < 3600) {
diff = Math.round(diff/60);
return diff + " minute" + (diff == 1 ? "" : "s") + end;
} else if(diff < 3600*24 && date.getDay() == now.getDay()) {
diff = Math.round(diff/3600);
return diff + " hour" + (diff == 1 ? "" : "s") + end;
} else if(diff < 3600*24*7) {
diff = Math.round(diff/(3600*24));
if(diff == 1) {
return future ? "Tomorrow" : "Yesterday";
} else {
return diff + " days" + end;
}
} else {
return dojo.date.toShortDateString(date);
}
}
/**
* Retrieves the day of the week the Date is set to.
*
* @return The day of the week
*/
dojo.date.getDayOfWeekName = function (date) {
dojo.deprecated("dojo.date.getDayOfWeekName",
"use dojo.date.getDayName instead", "0.4");
return dojo.date.days[date.getDay()];
}
/**
* Retrieves the short day of the week name the Date is set to.
*
* @return The short day of the week name
*/
dojo.date.getShortDayOfWeekName = function (date) {
dojo.deprecated("dojo.date.getShortDayOfWeekName",
"use dojo.date.getDayShortName instead", "0.4");
return dojo.date.shortDays[date.getDay()];
}
/**
* Retrieves the short month name the Date is set to.
*
* @return The short month name
*/
dojo.date.getShortMonthName = function (date) {
dojo.deprecated("dojo.date.getShortMonthName",
"use dojo.date.getMonthShortName instead", "0.4");
return dojo.date.shortMonths[date.getMonth()];
}
/**
* Convert a Date to a SQL string, optionally ignoring the HH:MM:SS portion of the Date
*/
dojo.date.toSql = function(date, noTime) {
return dojo.date.format(date, "%F" + !noTime ? " %T" : "");
}
/**
* Convert a SQL date string to a JavaScript Date object
*/
dojo.date.fromSql = function(sqlDate) {
var parts = sqlDate.split(/[\- :]/g);
while(parts.length < 6) {
parts.push(0);
}
return new Date(parts[0], (parseInt(parts[1],10)-1), parts[2], parts[3], parts[4], parts[5]);
}

80
webapp/web/src/debug.js Normal file
View file

@ -0,0 +1,80 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/**
* Produce a line of debug output.
* Does nothing unless djConfig.isDebug is true.
* varargs, joined with ''.
* Caller should not supply a trailing "\n".
*/
dojo.debug = function(){
if (!djConfig.isDebug) { return; }
var args = arguments;
if(dj_undef("println", dojo.hostenv)){
dojo.raise("dojo.debug not available (yet?)");
}
var isJUM = dj_global["jum"] && !dj_global["jum"].isBrowser;
var s = [(isJUM ? "": "DEBUG: ")];
for(var i=0;i<args.length;++i){
if(!false && args[i] && args[i] instanceof Error){
var msg = "[" + args[i].name + ": " + dojo.errorToString(args[i]) +
(args[i].fileName ? ", file: " + args[i].fileName : "") +
(args[i].lineNumber ? ", line: " + args[i].lineNumber : "") + "]";
} else {
try {
var msg = String(args[i]);
} catch(e) {
if(dojo.render.html.ie) {
var msg = "[ActiveXObject]";
} else {
var msg = "[unknown]";
}
}
}
s.push(msg);
}
if(isJUM){ // this seems to be the only way to get JUM to "play nice"
jum.debug(s.join(" "));
}else{
dojo.hostenv.println(s.join(" "));
}
}
/**
* this is really hacky for now - just
* display the properties of the object
**/
dojo.debugShallow = function(obj){
if (!djConfig.isDebug) { return; }
dojo.debug('------------------------------------------------------------');
dojo.debug('Object: '+obj);
var props = [];
for(var prop in obj){
try {
props.push(prop + ': ' + obj[prop]);
} catch(E) {
props.push(prop + ': ERROR - ' + E.message);
}
}
props.sort();
for(var i = 0; i < props.length; i++) {
dojo.debug(props[i]);
}
dojo.debug('------------------------------------------------------------');
}
dojo.debugDeep = function(obj){
if (!djConfig.isDebug) { return; }
if (!dojo.uri || !dojo.uri.dojoUri){ return dojo.debug("You'll need to load dojo.uri.* for deep debugging - sorry!"); }
if (!window.open){ return dojo.debug('Deep debugging is only supported in host environments with window.open'); }
var win = window.open(dojo.uri.dojoUri("src/debug/deep.html"), '_blank', 'width=600, height=400, resizable=yes, scrollbars=yes, status=yes');
win.debugVar = obj;
}

View file

@ -0,0 +1,17 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.debug.Firebug");
if (console.log) {
dojo.hostenv.println=console.log;
} else {
dojo.debug("dojo.debug.Firebug requires Firebug > 0.4");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

View file

@ -0,0 +1,359 @@
<html>
<head>
<title>Deep Debugger</title>
<script>
var tableRows = {};
var tableCels = {};
var tableObjs = {};
var tablesBuilt = {};
var tableShows = {};
var tableHides = {};
// IE: nodes w/id need to be redeclared or getElementById is b0rked
var frame = null;
window.onload = function(){
// if IE loads this page too quickly (instantly) then
// window.debugVar might not have been set
window.setTimeout(startMeUp, 100);
}
function startMeUp(){
frame = document.getElementById('frame');
buildTable('root', frame, window.debugVar);
}
function buildTable(path, parent, obj){
var keys = [];
var vals = [];
for(var prop in obj){
keys.push(prop);
try {
vals[prop] = obj[prop];
} catch(E) {
vals[prop] = 'ERROR: ' + E.message;
}
}
keys.sort(keySorter);
if (!keys.length){
var div = document.createElement('div');
div.appendChild(document.createTextNode('Object has no properties.'));
parent.appendChild(div);
return;
}
var t = document.createElement('table');
t.border = "1";
var tb = document.createElement('tbody');
t.appendChild(tb);
for(var i = 0; i < keys.length; i++) {
buildTableRow(path+'-'+keys[i], tb, keys[i], vals[keys[i]]);
}
if (path == 'root'){
//t.style.width = '90%';
}
t.style.width = '100%';
parent.appendChild(t);
tablesBuilt[path] = true;
}
function buildTableRow(path, tb, name, value) {
var simpleType = typeof(value);
var createSubrow = (simpleType == 'object');
var complexType = simpleType;
if (simpleType == 'object'){
var cls = getConstructorClass(value);
if (cls){
if (cls == 'Object'){
}else if (cls == 'Array'){
complexType = 'array';
}else{
complexType += ' ('+cls+')';
}
}
}
/*var tr1 = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
var td3 = document.createElement('td');
var td4 = document.createElement('td');*/
var row = tb.rows.length;
var tr1 = tb.insertRow(row++);
var td1 = tr1.insertCell(0);
var td2 = tr1.insertCell(1);
var td3 = tr1.insertCell(2);
var td4 = tr1.insertCell(3);
tr1.style.verticalAlign = 'top';
td1.style.verticalAlign = 'middle';
td1.className = 'propPlus';
td2.className = 'propName';
td3.className = 'propType';
td4.className = 'propVal';
//tr1.appendChild(td1);
//tr1.appendChild(td2);
//tr1.appendChild(td3);
//tr1.appendChild(td4);
if (createSubrow){
var img1 = document.createElement('img');
img1.width = 9;
img1.height = 9;
img1.src = 'arrow_show.gif';
var a1 = document.createElement('a');
a1.appendChild(img1);
a1.href = '#';
a1.onclick = function(){ showTableRow(path); return false; };
var img2 = document.createElement('img');
img2.width = 9;
img2.height = 9;
img2.src = 'arrow_hide.gif';
var a2 = document.createElement('a');
a2.appendChild(img2);
a2.href = '#';
a2.onclick = function(){ hideTableRow(path); return false; };
a2.style.display = 'none';
tableShows[path] = a1;
tableHides[path] = a2;
td1.appendChild(a1);
td1.appendChild(a2);
}else{
var img = document.createElement('img');
img.width = 9;
img.height = 9;
img.src = 'spacer.gif';
td1.appendChild(img);
}
td2.appendChild(document.createTextNode(name));
td3.appendChild(document.createTextNode(complexType));
td4.appendChild(buildPreBlock(value));
//tb.appendChild(tr1);
if (createSubrow){
var tr2 = tb.insertRow(row++);
var td5 = tr2.insertCell(0);
var td6 = tr2.insertCell(1);
//var tr2 = document.createElement('tr');
//var td5 = document.createElement('td');
//var td6 = document.createElement('td');
td5.innerHTML = '&nbsp;';
//td6.innerHTML = '&nbsp;';
td6.colSpan = '3';
tr2.appendChild(td5);
tr2.appendChild(td6);
tr2.style.display = 'none';
tb.appendChild(tr2);
tableRows[path] = tr2;
tableCels[path] = td6;
tableObjs[path] = value;
}
}
function showTableRow(path){
var tr = tableRows[path];
var td = tableCels[path];
var a1 = tableShows[path];
var a2 = tableHides[path];
if (!tablesBuilt[path]){
//alert('building table for '+path);
buildTable(path, td, tableObjs[path]);
}
tr.style.display = 'table-row';
a1.style.display = 'none';
a2.style.display = 'inline';
}
function hideTableRow(path){
var tr = tableRows[path];
var a1 = tableShows[path];
var a2 = tableHides[path];
tr.style.display = 'none';
a1.style.display = 'inline';
a2.style.display = 'none';
}
function buildPreBlock(value){
//
// how many lines ?
//
var s = ''+value;
s = s.replace("\r\n", "\n");
s = s.replace("\r", "");
var lines = s.split("\n");
if (lines.length < 2){
if (lines[0].length < 60){
var pre = document.createElement('pre');
pre.appendChild(document.createTextNode(s));
return pre;
}
}
//
// multiple lines :(
//
var preview = lines[0].substr(0, 60) + ' ...';
var pre1 = document.createElement('pre');
pre1.appendChild(document.createTextNode(preview));
pre1.className = 'clicky';
var pre2 = document.createElement('pre');
pre2.appendChild(document.createTextNode(s));
pre2.style.display = 'none';
pre2.className = 'clicky';
pre1.onclick = function(){
pre1.style.display = 'none';
pre2.style.display = 'block';
}
pre2.onclick = function(){
pre1.style.display = 'block';
pre2.style.display = 'none';
}
var pre = document.createElement('div');
pre.appendChild(pre1);
pre.appendChild(pre2);
return pre;
}
function getConstructorClass(obj){
if (!obj.constructor || !obj.constructor.toString) return;
var m = obj.constructor.toString().match(/function\s*(\w+)/);
if (m && m.length == 2) return m[1];
return null;
}
function keySorter(a, b){
if (a == parseInt(a) && b == parseInt(b)){
return (parseInt(a) > parseInt(b)) ? 1 : ((parseInt(a) < parseInt(b)) ? -1 : 0);
}
// sort by lowercase string
var a2 = String(a).toLowerCase();
var b2 = String(b).toLowerCase();
return (a2 > b2) ? 1 : ((a2 < b2) ? -1 : 0);
}
</script>
<style>
body {
font-family: arial, helvetica, sans-serif;
}
table {
border-width: 0px;
border-spacing: 1px;
border-collapse: separate;
}
td {
border-width: 0px;
padding: 2px;
}
img {
border: 0;
}
pre {
margin: 0;
padding: 0;
white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
white-space: -pre-wrap; /* Opera 4 - 6 */
white-space: -o-pre-wrap; /* Opera 7 */
white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) http://www.w3.org/TR/css3-text/#white-space */
word-wrap: break-word; /* IE 5.5+ */
}
pre.clicky {
cursor: hand;
cursor: pointer;
}
td.propPlus {
width: 9px;
background-color: #ddd;
}
td.propName {
background-color: #ddd;
}
td.propType {
background-color: #ddd;
}
td.propVal {
background-color: #ddd;
}
</style>
</head>
<body>
<h2>Javascript Object Browser</h2>
<div id="frame"></div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

View file

@ -0,0 +1,175 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.lang");
dojo.provide("dojo.dnd.DragSource");
dojo.provide("dojo.dnd.DropTarget");
dojo.provide("dojo.dnd.DragObject");
dojo.provide("dojo.dnd.DragAndDrop");
dojo.dnd.DragSource = function(){
var dm = dojo.dnd.dragManager;
if(dm["registerDragSource"]){ // side-effect prevention
dm.registerDragSource(this);
}
}
dojo.lang.extend(dojo.dnd.DragSource, {
type: "",
onDragEnd: function(){
},
onDragStart: function(){
},
/*
* This function gets called when the DOM element was
* selected for dragging by the HtmlDragAndDropManager.
*/
onSelected: function(){
},
unregister: function(){
dojo.dnd.dragManager.unregisterDragSource(this);
},
reregister: function(){
dojo.dnd.dragManager.registerDragSource(this);
}
});
dojo.dnd.DragObject = function(){
var dm = dojo.dnd.dragManager;
if(dm["registerDragObject"]){ // side-effect prevention
dm.registerDragObject(this);
}
}
dojo.lang.extend(dojo.dnd.DragObject, {
type: "",
onDragStart: function(){
// gets called directly after being created by the DragSource
// default action is to clone self as icon
},
onDragMove: function(){
// this changes the UI for the drag icon
// "it moves itself"
},
onDragOver: function(){
},
onDragOut: function(){
},
onDragEnd: function(){
},
// normal aliases
onDragLeave: this.onDragOut,
onDragEnter: this.onDragOver,
// non-camel aliases
ondragout: this.onDragOut,
ondragover: this.onDragOver
});
dojo.dnd.DropTarget = function(){
if (this.constructor == dojo.dnd.DropTarget) { return; } // need to be subclassed
this.acceptedTypes = [];
dojo.dnd.dragManager.registerDropTarget(this);
}
dojo.lang.extend(dojo.dnd.DropTarget, {
acceptsType: function(type){
if(!dojo.lang.inArray(this.acceptedTypes, "*")){ // wildcard
if(!dojo.lang.inArray(this.acceptedTypes, type)) { return false; }
}
return true;
},
accepts: function(dragObjects){
if(!dojo.lang.inArray(this.acceptedTypes, "*")){ // wildcard
for (var i = 0; i < dragObjects.length; i++) {
if (!dojo.lang.inArray(this.acceptedTypes,
dragObjects[i].type)) { return false; }
}
}
return true;
},
onDragOver: function(){
},
onDragOut: function(){
},
onDragMove: function(){
},
onDropStart: function(){
},
onDrop: function(){
},
onDropEnd: function(){
}
});
// NOTE: this interface is defined here for the convenience of the DragManager
// implementor. It is expected that in most cases it will be satisfied by
// extending a native event (DOM event in HTML and SVG).
dojo.dnd.DragEvent = function(){
this.dragSource = null;
this.dragObject = null;
this.target = null;
this.eventStatus = "success";
//
// can be one of:
// [ "dropSuccess", "dropFailure", "dragMove",
// "dragStart", "dragEnter", "dragLeave"]
//
}
dojo.dnd.DragManager = function(){
/*
* The DragManager handles listening for low-level events and dispatching
* them to higher-level primitives like drag sources and drop targets. In
* order to do this, it must keep a list of the items.
*/
}
dojo.lang.extend(dojo.dnd.DragManager, {
selectedSources: [],
dragObjects: [],
dragSources: [],
registerDragSource: function(){},
dropTargets: [],
registerDropTarget: function(){},
lastDragTarget: null,
currentDragTarget: null,
onKeyDown: function(){},
onMouseOut: function(){},
onMouseMove: function(){},
onMouseUp: function(){}
});
// NOTE: despite the existance of the DragManager class, there will be a
// singleton drag manager provided by the renderer-specific D&D support code.
// It is therefore sane for us to assign instance variables to the DragManager
// prototype
// The renderer-specific file will define the following object:
// dojo.dnd.dragManager = null;

View file

@ -0,0 +1,475 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.dnd.HtmlDragAndDrop");
dojo.provide("dojo.dnd.HtmlDragSource");
dojo.provide("dojo.dnd.HtmlDropTarget");
dojo.provide("dojo.dnd.HtmlDragObject");
dojo.require("dojo.dnd.HtmlDragManager");
dojo.require("dojo.dnd.DragAndDrop");
dojo.require("dojo.dom");
dojo.require("dojo.style");
dojo.require("dojo.html");
dojo.require("dojo.html.extras");
dojo.require("dojo.lang.extras");
dojo.require("dojo.lfx.*");
dojo.require("dojo.event");
dojo.dnd.HtmlDragSource = function(node, type){
node = dojo.byId(node);
this.dragObjects = [];
this.constrainToContainer = false;
if(node){
this.domNode = node;
this.dragObject = node;
// register us
dojo.dnd.DragSource.call(this);
// set properties that might have been clobbered by the mixin
this.type = (type)||(this.domNode.nodeName.toLowerCase());
}
}
dojo.inherits(dojo.dnd.HtmlDragSource, dojo.dnd.DragSource);
dojo.lang.extend(dojo.dnd.HtmlDragSource, {
dragClass: "", // CSS classname(s) applied to node when it is being dragged
onDragStart: function(){
var dragObj = new dojo.dnd.HtmlDragObject(this.dragObject, this.type);
if(this.dragClass) { dragObj.dragClass = this.dragClass; }
if (this.constrainToContainer) {
dragObj.constrainTo(this.constrainingContainer || this.domNode.parentNode);
}
return dragObj;
},
setDragHandle: function(node){
node = dojo.byId(node);
dojo.dnd.dragManager.unregisterDragSource(this);
this.domNode = node;
dojo.dnd.dragManager.registerDragSource(this);
},
setDragTarget: function(node){
this.dragObject = node;
},
constrainTo: function(container) {
this.constrainToContainer = true;
if (container) {
this.constrainingContainer = container;
}
},
/*
*
* see dojo.dnd.DragSource.onSelected
*/
onSelected: function() {
for (var i=0; i<this.dragObjects.length; i++) {
dojo.dnd.dragManager.selectedSources.push(new dojo.dnd.HtmlDragSource(this.dragObjects[i]));
}
},
/**
* Register elements that should be dragged along with
* the actual DragSource.
*
* Example usage:
* var dragSource = new dojo.dnd.HtmlDragSource(...);
* // add a single element
* dragSource.addDragObjects(dojo.byId('id1'));
* // add multiple elements to drag along
* dragSource.addDragObjects(dojo.byId('id2'), dojo.byId('id3'));
*
* el A dom node to add to the drag list.
*/
addDragObjects: function(/*DOMNode*/ el) {
for (var i=0; i<arguments.length; i++) {
this.dragObjects.push(arguments[i]);
}
}
});
dojo.dnd.HtmlDragObject = function(node, type){
this.domNode = dojo.byId(node);
this.type = type;
this.constrainToContainer = false;
this.dragSource = null;
}
dojo.inherits(dojo.dnd.HtmlDragObject, dojo.dnd.DragObject);
dojo.lang.extend(dojo.dnd.HtmlDragObject, {
dragClass: "",
opacity: 0.5,
createIframe: true, // workaround IE6 bug
// if true, node will not move in X and/or Y direction
disableX: false,
disableY: false,
createDragNode: function() {
var node = this.domNode.cloneNode(true);
if(this.dragClass) { dojo.html.addClass(node, this.dragClass); }
if(this.opacity < 1) { dojo.style.setOpacity(node, this.opacity); }
if(node.tagName.toLowerCase() == "tr"){
// dojo.debug("Dragging table row")
// Create a table for the cloned row
var doc = this.domNode.ownerDocument;
var table = doc.createElement("table");
var tbody = doc.createElement("tbody");
tbody.appendChild(node);
table.appendChild(tbody);
// Set a fixed width to the cloned TDs
var domTds = this.domNode.childNodes;
var cloneTds = node.childNodes;
for(var i = 0; i < domTds.length; i++){
if((cloneTds[i])&&(cloneTds[i].style)){
cloneTds[i].style.width = dojo.style.getContentWidth(domTds[i]) + "px";
}
}
node = table;
}
if((dojo.render.html.ie55||dojo.render.html.ie60) && this.createIframe){
with(node.style) {
top="0px";
left="0px";
}
var outer = document.createElement("div");
outer.appendChild(node);
this.bgIframe = new dojo.html.BackgroundIframe(outer);
outer.appendChild(this.bgIframe.iframe);
node = outer;
}
node.style.zIndex = 999;
return node;
},
onDragStart: function(e){
dojo.html.clearSelection();
this.scrollOffset = dojo.html.getScrollOffset();
this.dragStartPosition = dojo.style.getAbsolutePosition(this.domNode, true);
this.dragOffset = {y: this.dragStartPosition.y - e.pageY,
x: this.dragStartPosition.x - e.pageX};
this.dragClone = this.createDragNode();
this.containingBlockPosition = this.domNode.offsetParent ?
dojo.style.getAbsolutePosition(this.domNode.offsetParent) : {x:0, y:0};
if (this.constrainToContainer) {
this.constraints = this.getConstraints();
}
// set up for dragging
with(this.dragClone.style){
position = "absolute";
top = this.dragOffset.y + e.pageY + "px";
left = this.dragOffset.x + e.pageX + "px";
}
document.body.appendChild(this.dragClone);
dojo.event.topic.publish('dragStart', { source: this } );
},
/** Return min/max x/y (relative to document.body) for this object) **/
getConstraints: function() {
if (this.constrainingContainer.nodeName.toLowerCase() == 'body') {
var width = dojo.html.getViewportWidth();
var height = dojo.html.getViewportHeight();
var x = 0;
var y = 0;
} else {
width = dojo.style.getContentWidth(this.constrainingContainer);
height = dojo.style.getContentHeight(this.constrainingContainer);
x =
this.containingBlockPosition.x +
dojo.style.getPixelValue(this.constrainingContainer, "padding-left", true) +
dojo.style.getBorderExtent(this.constrainingContainer, "left");
y =
this.containingBlockPosition.y +
dojo.style.getPixelValue(this.constrainingContainer, "padding-top", true) +
dojo.style.getBorderExtent(this.constrainingContainer, "top");
}
return {
minX: x,
minY: y,
maxX: x + width - dojo.style.getOuterWidth(this.domNode),
maxY: y + height - dojo.style.getOuterHeight(this.domNode)
}
},
updateDragOffset: function() {
var scroll = dojo.html.getScrollOffset();
if(scroll.y != this.scrollOffset.y) {
var diff = scroll.y - this.scrollOffset.y;
this.dragOffset.y += diff;
this.scrollOffset.y = scroll.y;
}
if(scroll.x != this.scrollOffset.x) {
var diff = scroll.x - this.scrollOffset.x;
this.dragOffset.x += diff;
this.scrollOffset.x = scroll.x;
}
},
/** Moves the node to follow the mouse */
onDragMove: function(e){
this.updateDragOffset();
var x = this.dragOffset.x + e.pageX;
var y = this.dragOffset.y + e.pageY;
if (this.constrainToContainer) {
if (x < this.constraints.minX) { x = this.constraints.minX; }
if (y < this.constraints.minY) { y = this.constraints.minY; }
if (x > this.constraints.maxX) { x = this.constraints.maxX; }
if (y > this.constraints.maxY) { y = this.constraints.maxY; }
}
this.setAbsolutePosition(x, y);
dojo.event.topic.publish('dragMove', { source: this } );
},
/**
* Set the position of the drag clone. (x,y) is relative to <body>.
*/
setAbsolutePosition: function(x, y){
// The drag clone is attached to document.body so this is trivial
if(!this.disableY) { this.dragClone.style.top = y + "px"; }
if(!this.disableX) { this.dragClone.style.left = x + "px"; }
},
/**
* If the drag operation returned a success we reomve the clone of
* ourself from the original position. If the drag operation returned
* failure we slide back over to where we came from and end the operation
* with a little grace.
*/
onDragEnd: function(e){
switch(e.dragStatus){
case "dropSuccess":
dojo.dom.removeNode(this.dragClone);
this.dragClone = null;
break;
case "dropFailure": // slide back to the start
var startCoords = dojo.style.getAbsolutePosition(this.dragClone, true);
// offset the end so the effect can be seen
var endCoords = [this.dragStartPosition.x + 1,
this.dragStartPosition.y + 1];
// animate
var line = new dojo.lfx.Line(startCoords, endCoords);
var anim = new dojo.lfx.Animation(500, line, dojo.lfx.easeOut);
var dragObject = this;
dojo.event.connect(anim, "onAnimate", function(e) {
dragObject.dragClone.style.left = e[0] + "px";
dragObject.dragClone.style.top = e[1] + "px";
});
dojo.event.connect(anim, "onEnd", function (e) {
// pause for a second (not literally) and disappear
dojo.lang.setTimeout(function() {
dojo.dom.removeNode(dragObject.dragClone);
// Allow drag clone to be gc'ed
dragObject.dragClone = null;
},
200);
});
anim.play();
break;
}
// shortly the browser will fire an onClick() event,
// but since this was really a drag, just squelch it
dojo.event.connect(this.domNode, "onclick", this, "squelchOnClick");
dojo.event.topic.publish('dragEnd', { source: this } );
},
squelchOnClick: function(e){
// squelch this onClick() event because it's the result of a drag (it's not a real click)
e.preventDefault();
// but if a real click comes along, allow it
dojo.event.disconnect(this.domNode, "onclick", this, "squelchOnClick");
},
constrainTo: function(container) {
this.constrainToContainer=true;
if (container) {
this.constrainingContainer = container;
} else {
this.constrainingContainer = this.domNode.parentNode;
}
}
});
dojo.dnd.HtmlDropTarget = function(node, types){
if (arguments.length == 0) { return; }
this.domNode = dojo.byId(node);
dojo.dnd.DropTarget.call(this);
if(types && dojo.lang.isString(types)) {
types = [types];
}
this.acceptedTypes = types || [];
}
dojo.inherits(dojo.dnd.HtmlDropTarget, dojo.dnd.DropTarget);
dojo.lang.extend(dojo.dnd.HtmlDropTarget, {
onDragOver: function(e){
if(!this.accepts(e.dragObjects)){ return false; }
// cache the positions of the child nodes
this.childBoxes = [];
for (var i = 0, child; i < this.domNode.childNodes.length; i++) {
child = this.domNode.childNodes[i];
if (child.nodeType != dojo.dom.ELEMENT_NODE) { continue; }
var pos = dojo.style.getAbsolutePosition(child, true);
var height = dojo.style.getInnerHeight(child);
var width = dojo.style.getInnerWidth(child);
this.childBoxes.push({top: pos.y, bottom: pos.y+height,
left: pos.x, right: pos.x+width, node: child});
}
// TODO: use dummy node
return true;
},
_getNodeUnderMouse: function(e){
// find the child
for (var i = 0, child; i < this.childBoxes.length; i++) {
with (this.childBoxes[i]) {
if (e.pageX >= left && e.pageX <= right &&
e.pageY >= top && e.pageY <= bottom) { return i; }
}
}
return -1;
},
createDropIndicator: function() {
this.dropIndicator = document.createElement("div");
with (this.dropIndicator.style) {
position = "absolute";
zIndex = 999;
borderTopWidth = "1px";
borderTopColor = "black";
borderTopStyle = "solid";
width = dojo.style.getInnerWidth(this.domNode) + "px";
left = dojo.style.getAbsoluteX(this.domNode, true) + "px";
}
},
onDragMove: function(e, dragObjects){
var i = this._getNodeUnderMouse(e);
if(!this.dropIndicator){
this.createDropIndicator();
}
if(i < 0) {
if(this.childBoxes.length) {
var before = (dojo.html.gravity(this.childBoxes[0].node, e) & dojo.html.gravity.NORTH);
} else {
var before = true;
}
} else {
var child = this.childBoxes[i];
var before = (dojo.html.gravity(child.node, e) & dojo.html.gravity.NORTH);
}
this.placeIndicator(e, dragObjects, i, before);
if(!dojo.html.hasParent(this.dropIndicator)) {
document.body.appendChild(this.dropIndicator);
}
},
/**
* Position the horizontal line that indicates "insert between these two items"
*/
placeIndicator: function(e, dragObjects, boxIndex, before) {
with(this.dropIndicator.style){
if (boxIndex < 0) {
if (this.childBoxes.length) {
top = (before ? this.childBoxes[0].top
: this.childBoxes[this.childBoxes.length - 1].bottom) + "px";
} else {
top = dojo.style.getAbsoluteY(this.domNode, true) + "px";
}
} else {
var child = this.childBoxes[boxIndex];
top = (before ? child.top : child.bottom) + "px";
}
}
},
onDragOut: function(e) {
if(this.dropIndicator) {
dojo.dom.removeNode(this.dropIndicator);
delete this.dropIndicator;
}
},
/**
* Inserts the DragObject as a child of this node relative to the
* position of the mouse.
*
* @return true if the DragObject was inserted, false otherwise
*/
onDrop: function(e){
this.onDragOut(e);
var i = this._getNodeUnderMouse(e);
if (i < 0) {
if (this.childBoxes.length) {
if (dojo.html.gravity(this.childBoxes[0].node, e) & dojo.html.gravity.NORTH) {
return this.insert(e, this.childBoxes[0].node, "before");
} else {
return this.insert(e, this.childBoxes[this.childBoxes.length-1].node, "after");
}
}
return this.insert(e, this.domNode, "append");
}
var child = this.childBoxes[i];
if (dojo.html.gravity(child.node, e) & dojo.html.gravity.NORTH) {
return this.insert(e, child.node, "before");
} else {
return this.insert(e, child.node, "after");
}
},
insert: function(e, refNode, position) {
var node = e.dragObject.domNode;
if(position == "before") {
return dojo.html.insertBefore(node, refNode);
} else if(position == "after") {
return dojo.html.insertAfter(node, refNode);
} else if(position == "append") {
refNode.appendChild(node);
return true;
}
return false;
}
});

View file

@ -0,0 +1,475 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.dnd.HtmlDragManager");
dojo.require("dojo.dnd.DragAndDrop");
dojo.require("dojo.event.*");
dojo.require("dojo.lang.array");
dojo.require("dojo.html");
dojo.require("dojo.style");
// NOTE: there will only ever be a single instance of HTMLDragManager, so it's
// safe to use prototype properties for book-keeping.
dojo.dnd.HtmlDragManager = function(){
}
dojo.inherits(dojo.dnd.HtmlDragManager, dojo.dnd.DragManager);
dojo.lang.extend(dojo.dnd.HtmlDragManager, {
/**
* There are several sets of actions that the DnD code cares about in the
* HTML context:
* 1.) mouse-down ->
* (draggable selection)
* (dragObject generation)
* mouse-move ->
* (draggable movement)
* (droppable detection)
* (inform droppable)
* (inform dragObject)
* mouse-up
* (inform/destroy dragObject)
* (inform draggable)
* (inform droppable)
* 2.) mouse-down -> mouse-down
* (click-hold context menu)
* 3.) mouse-click ->
* (draggable selection)
* shift-mouse-click ->
* (augment draggable selection)
* mouse-down ->
* (dragObject generation)
* mouse-move ->
* (draggable movement)
* (droppable detection)
* (inform droppable)
* (inform dragObject)
* mouse-up
* (inform draggable)
* (inform droppable)
* 4.) mouse-up
* (clobber draggable selection)
*/
disabled: false, // to kill all dragging!
nestedTargets: false,
mouseDownTimer: null, // used for click-hold operations
dsCounter: 0,
dsPrefix: "dojoDragSource",
// dimension calculation cache for use durring drag
dropTargetDimensions: [],
currentDropTarget: null,
// currentDropTargetPoints: null,
previousDropTarget: null,
_dragTriggered: false,
selectedSources: [],
dragObjects: [],
// mouse position properties
currentX: null,
currentY: null,
lastX: null,
lastY: null,
mouseDownX: null,
mouseDownY: null,
threshold: 7,
dropAcceptable: false,
cancelEvent: function(e){ e.stopPropagation(); e.preventDefault();},
// method over-rides
registerDragSource: function(ds){
if(ds["domNode"]){
// FIXME: dragSource objects SHOULD have some sort of property that
// references their DOM node, we shouldn't just be passing nodes and
// expecting it to work.
var dp = this.dsPrefix;
var dpIdx = dp+"Idx_"+(this.dsCounter++);
ds.dragSourceId = dpIdx;
this.dragSources[dpIdx] = ds;
ds.domNode.setAttribute(dp, dpIdx);
// so we can drag links
if(dojo.render.html.ie){
dojo.event.connect(ds.domNode, "ondragstart", this.cancelEvent);
}
}
},
unregisterDragSource: function(ds){
if (ds["domNode"]){
var dp = this.dsPrefix;
var dpIdx = ds.dragSourceId;
delete ds.dragSourceId;
delete this.dragSources[dpIdx];
ds.domNode.setAttribute(dp, null);
}
if(dojo.render.html.ie){
dojo.event.disconnect(ds.domNode, "ondragstart", this.cancelEvent );
}
},
registerDropTarget: function(dt){
this.dropTargets.push(dt);
},
unregisterDropTarget: function(dt){
var index = dojo.lang.find(this.dropTargets, dt, true);
if (index>=0) {
this.dropTargets.splice(index, 1);
}
},
/**
* Get the DOM element that is meant to drag.
* Loop through the parent nodes of the event target until
* the element is found that was created as a DragSource and
* return it.
*
* @param event object The event for which to get the drag source.
*/
getDragSource: function(e){
var tn = e.target;
if(tn === document.body){ return; }
var ta = dojo.html.getAttribute(tn, this.dsPrefix);
while((!ta)&&(tn)){
tn = tn.parentNode;
if((!tn)||(tn === document.body)){ return; }
ta = dojo.html.getAttribute(tn, this.dsPrefix);
}
return this.dragSources[ta];
},
onKeyDown: function(e){
},
onMouseDown: function(e){
if(this.disabled) { return; }
// only begin on left click
if(dojo.render.html.ie) {
if(e.button != 1) { return; }
} else if(e.which != 1) {
return;
}
var target = e.target.nodeType == dojo.dom.TEXT_NODE ?
e.target.parentNode : e.target;
// do not start drag involvement if the user is interacting with
// a form element.
if(dojo.html.isTag(target, "button", "textarea", "input", "select", "option")) {
return;
}
// find a selection object, if one is a parent of the source node
var ds = this.getDragSource(e);
// this line is important. if we aren't selecting anything then
// we need to return now, so preventDefault() isn't called, and thus
// the event is propogated to other handling code
if(!ds){ return; }
if(!dojo.lang.inArray(this.selectedSources, ds)){
this.selectedSources.push(ds);
ds.onSelected();
}
this.mouseDownX = e.pageX;
this.mouseDownY = e.pageY;
// Must stop the mouse down from being propogated, or otherwise can't
// drag links in firefox.
// WARNING: preventing the default action on all mousedown events
// prevents user interaction with the contents.
e.preventDefault();
dojo.event.connect(document, "onmousemove", this, "onMouseMove");
},
onMouseUp: function(e, cancel){
// if we aren't dragging then ignore the mouse-up
// (in particular, don't call preventDefault(), because other
// code may need to process this event)
if(this.selectedSources.length==0){
return;
}
this.mouseDownX = null;
this.mouseDownY = null;
this._dragTriggered = false;
// e.preventDefault();
e.dragSource = this.dragSource;
if((!e.shiftKey)&&(!e.ctrlKey)){
if(this.currentDropTarget) {
this.currentDropTarget.onDropStart();
}
dojo.lang.forEach(this.dragObjects, function(tempDragObj){
var ret = null;
if(!tempDragObj){ return; }
if(this.currentDropTarget) {
e.dragObject = tempDragObj;
// NOTE: we can't get anything but the current drop target
// here since the drag shadow blocks mouse-over events.
// This is probelematic for dropping "in" something
var ce = this.currentDropTarget.domNode.childNodes;
if(ce.length > 0){
e.dropTarget = ce[0];
while(e.dropTarget == tempDragObj.domNode){
e.dropTarget = e.dropTarget.nextSibling;
}
}else{
e.dropTarget = this.currentDropTarget.domNode;
}
if(this.dropAcceptable){
ret = this.currentDropTarget.onDrop(e);
}else{
this.currentDropTarget.onDragOut(e);
}
}
e.dragStatus = this.dropAcceptable && ret ? "dropSuccess" : "dropFailure";
// decouple the calls for onDragEnd, so they don't block the execution here
// ie. if the onDragEnd would call an alert, the execution here is blocked until the
// user has confirmed the alert box and then the rest of the dnd code is executed
// while the mouse doesnt "hold" the dragged object anymore ... and so on
dojo.lang.delayThese([
function() {
// in FF1.5 this throws an exception, see
// http://dojotoolkit.org/pipermail/dojo-interest/2006-April/006751.html
try{
tempDragObj.dragSource.onDragEnd(e)
} catch(err) {
// since the problem seems passing e, we just copy all
// properties and try the copy ...
var ecopy = {};
for (var i in e) {
if (i=="type") { // the type property contains the exception, no idea why...
ecopy.type = "mouseup";
continue;
}
ecopy[i] = e[i];
}
tempDragObj.dragSource.onDragEnd(ecopy);
}
}
, function() {tempDragObj.onDragEnd(e)}]);
}, this);
this.selectedSources = [];
this.dragObjects = [];
this.dragSource = null;
if(this.currentDropTarget) {
this.currentDropTarget.onDropEnd();
}
}
dojo.event.disconnect(document, "onmousemove", this, "onMouseMove");
this.currentDropTarget = null;
},
onScroll: function(){
for(var i = 0; i < this.dragObjects.length; i++) {
if(this.dragObjects[i].updateDragOffset) {
this.dragObjects[i].updateDragOffset();
}
}
// TODO: do not recalculate, only adjust coordinates
this.cacheTargetLocations();
},
_dragStartDistance: function(x, y){
if((!this.mouseDownX)||(!this.mouseDownX)){
return;
}
var dx = Math.abs(x-this.mouseDownX);
var dx2 = dx*dx;
var dy = Math.abs(y-this.mouseDownY);
var dy2 = dy*dy;
return parseInt(Math.sqrt(dx2+dy2), 10);
},
cacheTargetLocations: function(){
this.dropTargetDimensions = [];
dojo.lang.forEach(this.dropTargets, function(tempTarget){
var tn = tempTarget.domNode;
if(!tn){ return; }
var ttx = dojo.style.getAbsoluteX(tn, true);
var tty = dojo.style.getAbsoluteY(tn, true);
this.dropTargetDimensions.push([
[ttx, tty], // upper-left
// lower-right
[ ttx+dojo.style.getInnerWidth(tn), tty+dojo.style.getInnerHeight(tn) ],
tempTarget
]);
//dojo.debug("Cached for "+tempTarget)
}, this);
//dojo.debug("Cache locations")
},
onMouseMove: function(e){
if((dojo.render.html.ie)&&(e.button != 1)){
// Oooops - mouse up occurred - e.g. when mouse was not over the
// window. I don't think we can detect this for FF - but at least
// we can be nice in IE.
this.currentDropTarget = null;
this.onMouseUp(e, true);
return;
}
// if we've got some sources, but no drag objects, we need to send
// onDragStart to all the right parties and get things lined up for
// drop target detection
if( (this.selectedSources.length)&&
(!this.dragObjects.length) ){
var dx;
var dy;
if(!this._dragTriggered){
this._dragTriggered = (this._dragStartDistance(e.pageX, e.pageY) > this.threshold);
if(!this._dragTriggered){ return; }
dx = e.pageX - this.mouseDownX;
dy = e.pageY - this.mouseDownY;
}
// the first element is always our dragSource, if there are multiple
// selectedSources (elements that move along) then the first one is the master
// and for it the events will be fired etc.
this.dragSource = this.selectedSources[0];
dojo.lang.forEach(this.selectedSources, function(tempSource){
if(!tempSource){ return; }
var tdo = tempSource.onDragStart(e);
if(tdo){
tdo.onDragStart(e);
// "bump" the drag object to account for the drag threshold
tdo.dragOffset.top += dy;
tdo.dragOffset.left += dx;
tdo.dragSource = tempSource;
this.dragObjects.push(tdo);
}
}, this);
/* clean previous drop target in dragStart */
this.previousDropTarget = null;
this.cacheTargetLocations();
}
// FIXME: we need to add dragSources and dragObjects to e
dojo.lang.forEach(this.dragObjects, function(dragObj){
if(dragObj){ dragObj.onDragMove(e); }
});
// if we have a current drop target, check to see if we're outside of
// it. If so, do all the actions that need doing.
if(this.currentDropTarget){
//dojo.debug(dojo.dom.hasParent(this.currentDropTarget.domNode))
var c = dojo.style.toCoordinateArray(this.currentDropTarget.domNode, true);
// var dtp = this.currentDropTargetPoints;
var dtp = [
[c[0],c[1]], [c[0]+c[2], c[1]+c[3]]
];
}
if((!this.nestedTargets)&&(dtp)&&(this.isInsideBox(e, dtp))){
if(this.dropAcceptable){
this.currentDropTarget.onDragMove(e, this.dragObjects);
}
}else{
// FIXME: need to fix the event object!
// see if we can find a better drop target
var bestBox = this.findBestTarget(e);
if(bestBox.target === null){
if(this.currentDropTarget){
this.currentDropTarget.onDragOut(e);
this.previousDropTarget = this.currentDropTarget;
this.currentDropTarget = null;
// this.currentDropTargetPoints = null;
}
this.dropAcceptable = false;
return;
}
if(this.currentDropTarget !== bestBox.target){
if(this.currentDropTarget){
this.previousDropTarget = this.currentDropTarget;
this.currentDropTarget.onDragOut(e);
}
this.currentDropTarget = bestBox.target;
// this.currentDropTargetPoints = bestBox.points;
e.dragObjects = this.dragObjects;
this.dropAcceptable = this.currentDropTarget.onDragOver(e);
}else{
if(this.dropAcceptable){
this.currentDropTarget.onDragMove(e, this.dragObjects);
}
}
}
},
findBestTarget: function(e) {
var _this = this;
var bestBox = new Object();
bestBox.target = null;
bestBox.points = null;
dojo.lang.every(this.dropTargetDimensions, function(tmpDA) {
if(!_this.isInsideBox(e, tmpDA))
return true;
bestBox.target = tmpDA[2];
bestBox.points = tmpDA;
// continue iterating only if _this.nestedTargets == true
return Boolean(_this.nestedTargets);
});
return bestBox;
},
isInsideBox: function(e, coords){
if( (e.pageX > coords[0][0])&&
(e.pageX < coords[1][0])&&
(e.pageY > coords[0][1])&&
(e.pageY < coords[1][1]) ){
return true;
}
return false;
},
onMouseOver: function(e){
},
onMouseOut: function(e){
}
});
dojo.dnd.dragManager = new dojo.dnd.HtmlDragManager();
// global namespace protection closure
(function(){
var d = document;
var dm = dojo.dnd.dragManager;
// set up event handlers on the document
dojo.event.connect(d, "onkeydown", dm, "onKeyDown");
dojo.event.connect(d, "onmouseover", dm, "onMouseOver");
dojo.event.connect(d, "onmouseout", dm, "onMouseOut");
dojo.event.connect(d, "onmousedown", dm, "onMouseDown");
dojo.event.connect(d, "onmouseup", dm, "onMouseUp");
// TODO: process scrolling of elements, not only window
dojo.event.connect(window, "onscroll", dm, "onScroll");
})();

View file

@ -0,0 +1,76 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.dnd.HtmlDragMove");
dojo.provide("dojo.dnd.HtmlDragMoveSource");
dojo.provide("dojo.dnd.HtmlDragMoveObject");
dojo.require("dojo.dnd.*");
dojo.dnd.HtmlDragMoveSource = function(node, type){
dojo.dnd.HtmlDragSource.call(this, node, type);
}
dojo.inherits(dojo.dnd.HtmlDragMoveSource, dojo.dnd.HtmlDragSource);
dojo.lang.extend(dojo.dnd.HtmlDragMoveSource, {
onDragStart: function(){
var dragObj = new dojo.dnd.HtmlDragMoveObject(this.dragObject, this.type);
if (this.constrainToContainer) {
dragObj.constrainTo(this.constrainingContainer);
}
return dragObj;
},
/*
* see dojo.dnd.HtmlDragSource.onSelected
*/
onSelected: function() {
for (var i=0; i<this.dragObjects.length; i++) {
dojo.dnd.dragManager.selectedSources.push(new dojo.dnd.HtmlDragMoveSource(this.dragObjects[i]));
}
}
});
dojo.dnd.HtmlDragMoveObject = function(node, type){
dojo.dnd.HtmlDragObject.call(this, node, type);
}
dojo.inherits(dojo.dnd.HtmlDragMoveObject, dojo.dnd.HtmlDragObject);
dojo.lang.extend(dojo.dnd.HtmlDragMoveObject, {
onDragEnd: function(e){
// shortly the browser will fire an onClick() event,
// but since this was really a drag, just squelch it
dojo.event.connect(this.domNode, "onclick", this, "squelchOnClick");
},
onDragStart: function(e){
dojo.html.clearSelection();
this.dragClone = this.domNode;
this.scrollOffset = dojo.html.getScrollOffset();
this.dragStartPosition = dojo.style.getAbsolutePosition(this.domNode, true);
this.dragOffset = {y: this.dragStartPosition.y - e.pageY,
x: this.dragStartPosition.x - e.pageX};
this.containingBlockPosition = this.domNode.offsetParent ?
dojo.style.getAbsolutePosition(this.domNode.offsetParent, true) : {x:0, y:0};
this.dragClone.style.position = "absolute";
if (this.constrainToContainer) {
this.constraints = this.getConstraints();
}
},
/**
* Set the position of the drag node. (x,y) is relative to <body>.
*/
setAbsolutePosition: function(x, y){
// The drag clone is attached to it's constraining container so offset for that
if(!this.disableY) { this.domNode.style.top = (y-this.containingBlockPosition.y) + "px"; }
if(!this.disableX) { this.domNode.style.left = (x-this.containingBlockPosition.x) + "px"; }
}
});

View file

@ -0,0 +1,28 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.dnd.Sortable");
dojo.require("dojo.dnd.*");
dojo.dnd.Sortable = function () {}
dojo.lang.extend(dojo.dnd.Sortable, {
ondragstart: function (e) {
var dragObject = e.target;
while (dragObject.parentNode && dragObject.parentNode != this) {
dragObject = dragObject.parentNode;
}
// TODO: should apply HtmlDropTarget interface to self
// TODO: should apply HtmlDragObject interface?
return dragObject;
}
});

View file

@ -0,0 +1,473 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/**
* TreeDrag* specialized on managing subtree drags
* It selects nodes and visualises what's going on,
* but delegates real actions upon tree to the controller
*
* This code is considered a part of controller
*/
dojo.provide("dojo.dnd.TreeDragAndDrop");
dojo.provide("dojo.dnd.TreeDragSource");
dojo.provide("dojo.dnd.TreeDropTarget");
dojo.provide("dojo.dnd.TreeDNDController");
dojo.require("dojo.dnd.HtmlDragAndDrop");
dojo.require("dojo.lang.func");
dojo.require("dojo.lang.array");
dojo.require("dojo.lang.extras");
dojo.dnd.TreeDragSource = function(node, syncController, type, treeNode){
this.controller = syncController;
this.treeNode = treeNode;
dojo.dnd.HtmlDragSource.call(this, node, type);
}
dojo.inherits(dojo.dnd.TreeDragSource, dojo.dnd.HtmlDragSource);
dojo.lang.extend(dojo.dnd.TreeDragSource, {
onDragStart: function(){
/* extend adds functions to prototype */
var dragObject = dojo.dnd.HtmlDragSource.prototype.onDragStart.call(this);
//dojo.debugShallow(dragObject)
dragObject.treeNode = this.treeNode;
dragObject.onDragStart = dojo.lang.hitch(dragObject, function(e) {
/* save selection */
this.savedSelectedNode = this.treeNode.tree.selector.selectedNode;
if (this.savedSelectedNode) {
this.savedSelectedNode.unMarkSelected();
}
var result = dojo.dnd.HtmlDragObject.prototype.onDragStart.apply(this, arguments);
/* remove background grid from cloned object */
var cloneGrid = this.dragClone.getElementsByTagName('img');
for(var i=0; i<cloneGrid.length; i++) {
cloneGrid.item(i).style.backgroundImage='url()';
}
return result;
});
dragObject.onDragEnd = function(e) {
/* restore selection */
if (this.savedSelectedNode) {
this.savedSelectedNode.markSelected();
}
//dojo.debug(e.dragStatus);
return dojo.dnd.HtmlDragObject.prototype.onDragEnd.apply(this, arguments);
}
//dojo.debug(dragObject.domNode.outerHTML)
return dragObject;
},
onDragEnd: function(e){
var res = dojo.dnd.HtmlDragSource.prototype.onDragEnd.call(this, e);
return res;
}
});
// .......................................
dojo.dnd.TreeDropTarget = function(domNode, controller, type, treeNode, DNDMode){
this.treeNode = treeNode;
this.controller = controller; // I will sync-ly process drops
this.DNDMode = DNDMode;
dojo.dnd.HtmlDropTarget.apply(this, [domNode, type]);
}
dojo.inherits(dojo.dnd.TreeDropTarget, dojo.dnd.HtmlDropTarget);
dojo.lang.extend(dojo.dnd.TreeDropTarget, {
autoExpandDelay: 1500,
autoExpandTimer: null,
position: null,
indicatorStyle: "2px black solid",
showIndicator: function(position) {
// do not change style too often, cause of blinking possible
if (this.position == position) {
return;
}
//dojo.debug(position)
this.hideIndicator();
this.position = position;
if (position == "before") {
this.treeNode.labelNode.style.borderTop = this.indicatorStyle;
} else if (position == "after") {
this.treeNode.labelNode.style.borderBottom = this.indicatorStyle;
} else if (position == "onto") {
this.treeNode.markSelected();
}
},
hideIndicator: function() {
this.treeNode.labelNode.style.borderBottom="";
this.treeNode.labelNode.style.borderTop="";
this.treeNode.unMarkSelected();
this.position = null;
},
// is the target possibly ok ?
// This function is run on dragOver, but drop possibility is also determined by position over node
// that's why acceptsWithPosition is called
// doesnt take index into account ( can change while moving mouse w/o changing target )
/**
* Coarse (tree-level) access check.
* We can't determine real accepts status w/o position
*/
onDragOver: function(e){
//dojo.debug("onDragOver for "+e);
var accepts = dojo.dnd.HtmlDropTarget.prototype.onDragOver.apply(this, arguments);
//dojo.debug("TreeDropTarget.onDragOver accepts:"+accepts)
if (accepts && this.treeNode.isFolder && !this.treeNode.isExpanded) {
this.setAutoExpandTimer();
}
return accepts;
},
/* Parent.onDragOver calls this function to get accepts status */
accepts: function(dragObjects) {
var accepts = dojo.dnd.HtmlDropTarget.prototype.accepts.apply(this, arguments);
if (!accepts) return false;
var sourceTreeNode = dragObjects[0].treeNode;
if (dojo.lang.isUndefined(sourceTreeNode) || !sourceTreeNode || !sourceTreeNode.isTreeNode) {
dojo.raise("Source is not TreeNode or not found");
}
if (sourceTreeNode === this.treeNode) return false;
return true;
},
setAutoExpandTimer: function() {
// set up autoexpand timer
var _this = this;
var autoExpand = function () {
if (dojo.dnd.dragManager.currentDropTarget === _this) {
_this.controller.expand(_this.treeNode);
}
}
this.autoExpandTimer = dojo.lang.setTimeout(autoExpand, _this.autoExpandDelay);
},
getAcceptPosition: function(e, sourceTreeNode) {
var DNDMode = this.DNDMode;
if (DNDMode & dojo.widget.Tree.prototype.DNDModes.ONTO &&
// check if ONTO is allowed localy
!(
!this.treeNode.actionIsDisabled(dojo.widget.TreeNode.prototype.actions.ADDCHILD) // check dynamically cause may change w/o regeneration of dropTarget
&& sourceTreeNode.parent !== this.treeNode
&& this.controller.canMove(sourceTreeNode, this.treeNode)
)
) {
// disable ONTO if can't move
DNDMode &= ~dojo.widget.Tree.prototype.DNDModes.ONTO;
}
var position = this.getPosition(e, DNDMode);
//dojo.debug(DNDMode & +" : "+position);
// if onto is here => it was allowed before, no accept check is needed
if (position=="onto" ||
(!this.isAdjacentNode(sourceTreeNode, position)
&& this.controller.canMove(sourceTreeNode, this.treeNode.parent)
)
) {
return position;
} else {
return false;
}
},
onDragOut: function(e) {
this.clearAutoExpandTimer();
this.hideIndicator();
},
clearAutoExpandTimer: function() {
if (this.autoExpandTimer) {
clearTimeout(this.autoExpandTimer);
this.autoExpandTimer = null;
}
},
onDragMove: function(e, dragObjects){
var sourceTreeNode = dragObjects[0].treeNode;
var position = this.getAcceptPosition(e, sourceTreeNode);
if (position) {
this.showIndicator(position);
}
},
isAdjacentNode: function(sourceNode, position) {
if (sourceNode === this.treeNode) return true;
if (sourceNode.getNextSibling() === this.treeNode && position=="before") return true;
if (sourceNode.getPreviousSibling() === this.treeNode && position=="after") return true;
return false;
},
/* get DNDMode and see which position e fits */
getPosition: function(e, DNDMode) {
node = dojo.byId(this.treeNode.labelNode);
var mousey = e.pageY || e.clientY + document.body.scrollTop;
var nodey = dojo.html.getAbsoluteY(node);
var height = dojo.html.getInnerHeight(node);
var relY = mousey - nodey;
var p = relY / height;
var position = ""; // "" <=> forbidden
if (DNDMode & dojo.widget.Tree.prototype.DNDModes.ONTO
&& DNDMode & dojo.widget.Tree.prototype.DNDModes.BETWEEN) {
if (p<=0.3) {
position = "before";
} else if (p<=0.7) {
position = "onto";
} else {
position = "after";
}
} else if (DNDMode & dojo.widget.Tree.prototype.DNDModes.BETWEEN) {
if (p<=0.5) {
position = "before";
} else {
position = "after";
}
}
else if (DNDMode & dojo.widget.Tree.prototype.DNDModes.ONTO) {
position = "onto";
}
return position;
},
getTargetParentIndex: function(sourceTreeNode, position) {
var index = position == "before" ? this.treeNode.getParentIndex() : this.treeNode.getParentIndex()+1;
if (this.treeNode.parent === sourceTreeNode.parent
&& this.treeNode.getParentIndex() > sourceTreeNode.getParentIndex()) {
index--; // dragging a node is different for simple move bacause of before-after issues
}
return index;
},
onDrop: function(e){
// onDragOut will clean position
var position = this.position;
//dojo.debug(position);
this.onDragOut(e);
var sourceTreeNode = e.dragObject.treeNode;
if (!dojo.lang.isObject(sourceTreeNode)) {
dojo.raise("TreeNode not found in dragObject")
}
if (position == "onto") {
return this.controller.move(sourceTreeNode, this.treeNode, 0);
} else {
var index = this.getTargetParentIndex(sourceTreeNode, position);
return this.controller.move(sourceTreeNode, this.treeNode.parent, index);
}
//dojo.debug('drop2');
}
});
dojo.dnd.TreeDNDController = function(treeController) {
// I use this controller to perform actions
this.treeController = treeController;
this.dragSources = {};
this.dropTargets = {};
}
dojo.lang.extend(dojo.dnd.TreeDNDController, {
listenTree: function(tree) {
//dojo.debug("Listen tree "+tree);
dojo.event.topic.subscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
dojo.event.topic.subscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
dojo.event.topic.subscribe(tree.eventNames.moveTo, this, "onMoveTo");
dojo.event.topic.subscribe(tree.eventNames.addChild, this, "onAddChild");
dojo.event.topic.subscribe(tree.eventNames.removeNode, this, "onRemoveNode");
dojo.event.topic.subscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
},
unlistenTree: function(tree) {
//dojo.debug("Listen tree "+tree);
dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode");
dojo.event.topic.unsubscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
dojo.event.topic.unsubscribe(tree.eventNames.moveTo, this, "onMoveTo");
dojo.event.topic.unsubscribe(tree.eventNames.addChild, this, "onAddChild");
dojo.event.topic.unsubscribe(tree.eventNames.removeNode, this, "onRemoveNode");
dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");
},
onTreeDestroy: function(message) {
this.unlistenTree(message.source);
// I'm not widget so don't use destroy() call and dieWithTree
},
onCreateDOMNode: function(message) {
this.registerDNDNode(message.source);
},
onAddChild: function(message) {
this.registerDNDNode(message.child);
},
onMoveFrom: function(message) {
var _this = this;
dojo.lang.forEach(
message.child.getDescendants(),
function(node) { _this.unregisterDNDNode(node); }
);
},
onMoveTo: function(message) {
var _this = this;
dojo.lang.forEach(
message.child.getDescendants(),
function(node) { _this.registerDNDNode(node); }
);
},
/**
* Controller(node model) creates DNDNodes because it passes itself to node for synchroneous drops processing
* I can't process DnD with events cause an event can't return result success/false
*/
registerDNDNode: function(node) {
if (!node.tree.DNDMode) return;
//dojo.debug("registerDNDNode "+node);
/* I drag label, not domNode, because large domNodes are very slow to copy and large to drag */
var source = null;
var target = null;
if (!node.actionIsDisabled(node.actions.MOVE)) {
//dojo.debug("reg source")
var source = new dojo.dnd.TreeDragSource(node.labelNode, this, node.tree.widgetId, node);
this.dragSources[node.widgetId] = source;
}
var target = new dojo.dnd.TreeDropTarget(node.labelNode, this.treeController, node.tree.DNDAcceptTypes, node, node.tree.DNDMode);
this.dropTargets[node.widgetId] = target;
},
unregisterDNDNode: function(node) {
if (this.dragSources[node.widgetId]) {
dojo.dnd.dragManager.unregisterDragSource(this.dragSources[node.widgetId]);
delete this.dragSources[node.widgetId];
}
if (this.dropTargets[node.widgetId]) {
dojo.dnd.dragManager.unregisterDropTarget(this.dropTargets[node.widgetId]);
delete this.dropTargets[node.widgetId];
}
}
});

View file

@ -0,0 +1,16 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: ["dojo.dnd.DragAndDrop"],
browser: ["dojo.dnd.HtmlDragAndDrop"],
dashboard: ["dojo.dnd.HtmlDragAndDrop"]
});
dojo.provide("dojo.dnd.*");

622
webapp/web/src/doc.js Normal file
View file

@ -0,0 +1,622 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.doc");
dojo.require("dojo.io.*");
dojo.require("dojo.event.topic");
dojo.require("dojo.rpc.JotService");
dojo.require("dojo.dom");
/*
* TODO:
*
* Package summary needs to compensate for "is"
* Handle host environments
* Deal with dojo.widget weirdness
* Parse parameters
* Limit function parameters to only the valid ones (Involves packing parameters onto meta during rewriting)
* Package display page
*
*/
dojo.doc._count = 0;
dojo.doc._keys = {};
dojo.doc._myKeys = [];
dojo.doc._callbacks = {function_names: []};
dojo.doc._cache = {}; // Saves the JSON objects in cache
dojo.doc._rpc = new dojo.rpc.JotService;
dojo.doc._rpc.serviceUrl = "http://dojotoolkit.org/~pottedmeat/jsonrpc.php";
dojo.lang.mixin(dojo.doc, {
functionNames: function(/*mixed*/ selectKey, /*Function*/ callback){
// summary: Returns an ordered list of package and function names.
dojo.debug("functionNames()");
if(!selectKey){
selectKey = ++dojo.doc._count;
}
dojo.doc._buildCache({
type: "function_names",
callbacks: [dojo.doc._functionNames, callback],
selectKey: selectKey
});
},
_functionNames: function(/*String*/ type, /*Array*/ data, /*Object*/ evt){
dojo.debug("_functionNames()");
var searchData = [];
for(var key in data){
// Add the package if it doesn't exist in its children
if(!dojo.lang.inArray(data[key], key)){
searchData.push([key, key]);
}
// Add the functions
for(var pkg_key in data[key]){
searchData.push([data[key][pkg_key], data[key][pkg_key]]);
}
}
searchData = searchData.sort(dojo.doc._sort);
if(evt.callbacks && evt.callbacks.length){
var callback = evt.callbacks.shift();
callback.call(null, type, searchData, evt);
}
},
getMeta: function(/*mixed*/ selectKey, /*Function*/ callback, /*Function*/ name, /*String?*/ id){
// summary: Gets information about a function in regards to its meta data
dojo.debug("getMeta(" + name + ")");
if(!selectKey){
selectKey = ++dojo.doc._count;
}
dojo.doc._buildCache({
type: "meta",
callbacks: [callback],
name: name,
id: id,
selectKey: selectKey
});
},
_getMeta: function(/*String*/ type, /*Object*/ data, /*Object*/ evt){
dojo.debug("_getMeta(" + evt.name + ") has package: " + evt.pkg + " with: " + type);
if("load" == type && evt.pkg){
evt.type = "meta";
dojo.doc._buildCache(evt);
}else{
if(evt.callbacks && evt.callbacks.length){
var callback = evt.callbacks.shift();
callback.call(null, "error", {}, evt);
}
}
},
getSrc: function(/*mixed*/ selectKey, /*Function*/ callback, /*String*/ name, /*String?*/ id){
// summary: Gets src file (created by the doc parser)
dojo.debug("getSrc()");
if(!selectKey){
selectKey = ++dojo.doc._count;
}
dojo.doc._buildCache({
type: "src",
callbacks: [callback],
name: name,
id: id,
selectKey: selectKey
});
},
_getSrc: function(/*String*/ type, /*Object*/ data, /*Object*/ evt){
dojo.debug("_getSrc()");
if(evt.pkg){
evt.type = "src";
dojo.doc._buildCache(evt);
}else{
if(evt.callbacks && evt.callbacks.length){
var callback = evt.callbacks.shift();
callback.call(null, "error", {}, evt);
}
}
},
getDoc: function(/*mixed*/ selectKey, /*Function*/ callback, /*String*/ name, /*String?*/ id){
// summary: Gets external documentation stored on jot
dojo.debug("getDoc()");
if(!selectKey){
selectKey = ++dojo.doc._count;
}
var input = {
type: "doc",
callbacks: [callback],
name: name,
id: id,
selectKey: selectKey
}
dojo.doc.functionPackage(dojo.doc._getDoc, input);
},
_getDoc: function(/*String*/ type, /*Object*/ data, /*Object*/ evt){
dojo.debug("_getDoc(" + evt.pkg + "/" + evt.name + ")");
dojo.doc._keys[evt.selectKey] = {count: 0};
var search = {};
search.forFormName = "DocFnForm";
search.limit = 1;
if(!evt.id){
search.filter = "it/DocFnForm/require = '" + evt.pkg + "' and it/DocFnForm/name = '" + evt.name + "' and not(it/DocFnForm/id)";
}else{
search.filter = "it/DocFnForm/require = '" + evt.pkg + "' and it/DocFnForm/name = '" + evt.name + "' and it/DocFnForm/id = '" + evt.id + "'";
}
dojo.debug(dojo.json.serialize(search));
dojo.doc._rpc.callRemote("search", search).addCallbacks(function(data){ evt.type = "fn"; dojo.doc._gotDoc("load", data.list[0], evt); }, function(data){ evt.type = "fn"; dojo.doc._gotDoc("error", {}, evt); });
search.forFormName = "DocParamForm";
if(!evt.id){
search.filter = "it/DocParamForm/fns = '" + evt.pkg + "=>" + evt.name + "'";
}else{
search.filter = "it/DocParamForm/fns = '" + evt.pkg + "=>" + evt.name + "=>" + evt.id + "'";
}
delete search.limit;
dojo.doc._rpc.callRemote("search", search).addCallbacks(function(data){ evt.type = "param"; dojo.doc._gotDoc("load", data.list, evt); }, function(data){ evt.type = "param"; dojo.doc._gotDoc("error", {}, evt); });
},
_gotDoc: function(/*String*/ type, /*Array*/ data, /*Object*/ evt){
dojo.debug("_gotDoc(" + evt.type + ") for " + evt.selectKey);
dojo.doc._keys[evt.selectKey][evt.type] = data;
if(++dojo.doc._keys[evt.selectKey].count == 2){
dojo.debug("_gotDoc() finished");
var keys = dojo.doc._keys[evt.selectKey];
var description = '';
if(!keys.fn){
keys.fn = {}
}
if(keys.fn["main/text"]){
description = dojo.dom.createDocumentFromText(keys.fn["main/text"]).childNodes[0].innerHTML;
if(!description){
description = keys.fn["main/text"];
}
}
data = {
description: description,
returns: keys.fn["DocFnForm/returns"],
id: keys.fn["DocFnForm/id"],
parameters: {},
variables: []
}
for(var i = 0, param; param = keys["param"][i]; i++){
data.parameters[param["DocParamForm/name"]] = {
description: param["DocParamForm/desc"]
};
}
delete dojo.doc._keys[evt.selectKey];
if(evt.callbacks && evt.callbacks.length){
var callback = evt.callbacks.shift();
callback.call(null, "load", data, evt);
}
}
},
getPkgMeta: function(/*mixed*/ selectKey, /*Function*/ callback, /*String*/ name){
dojo.debug("getPkgMeta(" + name + ")");
if(!selectKey){
selectKey = ++dojo.doc._count;
}
dojo.doc._buildCache({
type: "pkgmeta",
callbacks: [callback],
name: name,
selectKey: selectKey
});
},
_getPkgMeta: function(/*Object*/ input){
dojo.debug("_getPkgMeta(" + input.name + ")");
input.type = "pkgmeta";
dojo.doc._buildCache(input);
},
_onDocSearch: function(/*Object*/ input){
dojo.debug("_onDocSearch(" + input.name + ")");
if(!input.name){
return;
}
if(!input.selectKey){
input.selectKey = ++dojo.doc._count;
}
input.callbacks = [dojo.doc._onDocSearchFn];
input.name = input.name.toLowerCase();
input.type = "function_names";
dojo.doc._buildCache(input);
},
_onDocSearchFn: function(/*String*/ type, /*Array*/ data, /*Object*/ evt){
dojo.debug("_onDocSearchFn(" + evt.name + ")");
var packages = [];
var size = 0;
pkgLoop:
for(var pkg in data){
for(var i = 0, fn; fn = data[pkg][i]; i++){
if(fn.toLowerCase().indexOf(evt.name) != -1){
// Build a list of all packages that need to be loaded and their loaded state.
++size;
packages.push(pkg);
continue pkgLoop;
}
}
}
dojo.doc._keys[evt.selectKey] = {};
dojo.doc._keys[evt.selectKey].pkgs = packages;
dojo.doc._keys[evt.selectKey].pkg = evt.name; // Remember what we were searching for
dojo.doc._keys[evt.selectKey].loaded = 0;
for(var i = 0, pkg; pkg = packages[i]; i++){
setTimeout("dojo.doc.getPkgMeta(\"" + evt.selectKey + "\", dojo.doc._onDocResults, \"" + pkg + "\");", i*10);
}
},
_onDocResults: function(/*String*/ type, /*Object*/ data, /*Object*/ evt){
dojo.debug("_onDocResults(" + evt.name + "/" + dojo.doc._keys[evt.selectKey].pkg + ") " + type);
++dojo.doc._keys[evt.selectKey].loaded;
if(dojo.doc._keys[evt.selectKey].loaded == dojo.doc._keys[evt.selectKey].pkgs.length){
var info = dojo.doc._keys[evt.selectKey];
var pkgs = info.pkgs;
var name = info.pkg;
delete dojo.doc._keys[evt.selectKey];
var results = {selectKey: evt.selectKey, docResults: []};
data = dojo.doc._cache;
for(var i = 0, pkg; pkg = pkgs[i]; i++){
if(!data[pkg]){
continue;
}
for(var fn in data[pkg]["meta"]){
if(fn.toLowerCase().indexOf(name) == -1){
continue;
}
if(fn != "requires"){
for(var pId in data[pkg]["meta"][fn]){
var result = {
pkg: pkg,
name: fn,
summary: ""
}
if(data[pkg]["meta"][fn][pId].summary){
result.summary = data[pkg]["meta"][fn][pId].summary;
}
results.docResults.push(result);
}
}
}
}
dojo.debug("Publishing docResults");
dojo.doc._printResults(results);
}
},
_printResults: function(results){
dojo.debug("_printResults(): called");
// summary: Call this function to send the /doc/results topic
},
_onDocSelectFunction: function(/*Object*/ input){
// summary: Get doc, meta, and src
var name = input.name;
var selectKey = selectKey;
dojo.debug("_onDocSelectFunction(" + name + ")");
if(!name){
return false;
}
if(!selectKey){
selectKey = ++dojo.doc._count;
}
dojo.doc._keys[selectKey] = {size: 0};
dojo.doc._myKeys[++dojo.doc._count] = {selectKey: selectKey, type: "meta"}
dojo.doc.getMeta(dojo.doc._count, dojo.doc._onDocSelectResults, name);
dojo.doc._myKeys[++dojo.doc._count] = {selectKey: selectKey, type: "src"}
dojo.doc.getSrc(dojo.doc._count, dojo.doc._onDocSelectResults, name);
dojo.doc._myKeys[++dojo.doc._count] = {selectKey: selectKey, type: "doc"}
dojo.doc.getDoc(dojo.doc._count, dojo.doc._onDocSelectResults, name);
},
_onDocSelectResults: function(/*String*/ type, /*Object*/ data, /*Object*/ evt){
dojo.debug("dojo.doc._onDocSelectResults(" + evt.type + ", " + evt.name + ")");
var myKey = dojo.doc._myKeys[evt.selectKey];
dojo.doc._keys[myKey.selectKey][myKey.type] = data;
dojo.doc._keys[myKey.selectKey].size;
if(++dojo.doc._keys[myKey.selectKey].size == 3){
var key = dojo.lang.mixin(evt, dojo.doc._keys[myKey.selectKey]);
delete key.size;
dojo.debug("Publishing docFunctionDetail");
dojo.doc._printFunctionDetail(key);
delete dojo.doc._keys[myKey.selectKey];
delete dojo.doc._myKeys[evt.selectKey];
}
},
_printFunctionDetail: function(results) {
// summary: Call this function to send the /doc/functionDetail topic event
},
_buildCache: function(/*Object*/ input){
var type = input.type;
var pkg = input.pkg;
var callbacks = input.callbacks;
var id = input.id;
if(!id){
id = "_";
}
var name = input.name;
dojo.debug("_buildCache() type: " + type);
if(type == "function_names"){
if(!dojo.doc._cache["function_names"]){
dojo.debug("_buildCache() new cache");
if(callbacks && callbacks.length){
dojo.doc._callbacks.function_names.push([input, callbacks.shift()]);
}
dojo.doc._cache["function_names"] = {loading: true};
dojo.io.bind({
url: "json/function_names",
mimetype: "text/json",
error: function(type, data, evt){
dojo.debug("Unable to load function names");
for(var i = 0, callback; callback = dojo.doc._callbacks.function_names[i]; i++){
callback[1].call(null, "error", {}, callback[0]);
}
},
load: function(type, data, evt){
dojo.doc._cache['function_names'] = data;
for(var i = 0, callback; callback = dojo.doc._callbacks.function_names[i]; i++){
callback[1].call(null, "load", data, callback[0]);
}
}
});
}else if(dojo.doc._cache["function_names"].loading){
dojo.debug("_buildCache() loading cache");
if(callbacks && callbacks.length){
dojo.doc._callbacks.function_names.push([input, callbacks.shift()]);
}
}else{
dojo.debug("_buildCache() from cache");
if(callbacks && callbacks.length){
var callback = callbacks.shift();
callback.call(null, "load", dojo.doc._cache["function_names"], input);
}
}
}else if(type == "meta" || type == "src"){
if(!pkg){
if(type == "meta"){
dojo.doc.functionPackage(dojo.doc._getMeta, input);
}else{
dojo.doc.functionPackage(dojo.doc._getSrc, input);
}
}else{
try{
var cached = dojo.doc._cache[pkg][name][id][type];
}catch(e){}
if(cached){
if(callbacks && callbacks.length){
var callback = callbacks.shift();
callback.call(null, "load", cached, input);
return;
}
}
dojo.debug("Finding " + type + " for: " + pkg + ", function: " + name + ", id: " + id);
var mimetype = "text/json";
if(type == "src"){
mimetype = "text/plain"
}
var url = "json/" + pkg + "/" + name + "/" + id + "/" + type;
dojo.io.bind({
url: url,
input: input,
mimetype: mimetype,
error: function(type, data, evt, args){
var input = args.input;
var pkg = input.pkg;
var type = input.type;
var callbacks = input.callbacks;
var id = input.id;
var name = input.name;
if(callbacks && callbacks.length){
if(!data){
data = {};
}
if(!dojo.doc._cache[pkg]){
dojo.doc._cache[pkg] = {};
}
if(!dojo.doc._cache[pkg][name]){
dojo.doc._cache[pkg][name] = {};
}
if(type == "meta"){
data.sig = dojo.doc._cache[pkg][name][id].sig;
data.params = dojo.doc._cache[pkg][name][id].params;
}
var callback = callbacks.shift();
callback.call(null, "error", data, args.input);
}
},
load: function(type, data, evt, args){
var input = args.input;
var pkg = input.pkg;
var type = input.type;
var id = input.id;
var name = input.name;
var cache = dojo.doc._cache;
dojo.debug("_buildCache() loaded " + type);
if(!data){
data = {};
}
if(!cache[pkg]){
dojo.doc._cache[pkg] = {};
}
if(!cache[pkg][name]){
dojo.doc._cache[pkg][name] = {};
}
if(!cache[pkg][name][id]){
dojo.doc._cache[pkg][name][id] = {};
}
if(!cache[pkg][name][id].meta){
dojo.doc._cache[pkg][name][id].meta = {};
}
dojo.doc._cache[pkg][name][id][type] = data;
if(callbacks && callbacks.length){
var callback = callbacks.shift();
callback.call(null, "load", data, args.input);
}
}
});
}
}else if(type == "pkgmeta"){
try{
var cached = dojo.doc._cache[name]["meta"];
}catch(e){}
if(cached){
if(callbacks && callbacks.length){
var callback = callbacks.shift();
callback.call(null, "load", cached, input);
return;
}
}
dojo.debug("Finding package meta for: " + name);
dojo.io.bind({
url: "json/" + name + "/meta",
input: input,
mimetype: "text/json",
error: function(type, data, evt, args){
var callbacks = args.input.callbacks;
if(callbacks && callbacks.length){
var callback = callbacks.shift();
callback.call(null, "error", {}, args.input);
}
},
load: function(type, data, evt, args){
var pkg = args.input.name;
var cache = dojo.doc._cache;
dojo.debug("_buildCache() loaded for: " + pkg);
if(!cache[pkg]){
dojo.doc._cache[pkg] = {};
}
if(!cache[pkg]["meta"]){
dojo.doc._cache[pkg]["meta"] = {};
}
var methods = data.methods;
if(methods){
for(var method in methods){
if (method == "is") {
continue;
}
for(var pId in methods[method]){
if(!cache[pkg]["meta"][method]){
dojo.doc._cache[pkg]["meta"][method] = {};
}
if(!cache[pkg]["meta"][method][pId]){
dojo.doc._cache[pkg]["meta"][method][pId] = {};
}
dojo.doc._cache[pkg]["meta"][method][pId].summary = methods[method][pId];
}
}
}
dojo.doc._cache[pkg]["meta"].methods = methods;
var requires = data.requires;
if(requires){
dojo.doc._cache[pkg]["meta"].requires = requires;
}
if(callbacks && callbacks.length){
var callback = callbacks.shift();
callback.call(null, "load", methods, input);
}
}
});
}
},
selectFunction: function(/*String*/ name, /*String?*/ id){
// summary: The combined information
},
savePackage: function(/*String*/ name, /*String*/ description){
dojo.doc._rpc.callRemote(
"saveForm",
{
form: "DocPkgForm",
path: "/WikiHome/DojoDotDoc/id",
pname1: "main/text",
pvalue1: "Test"
}
).addCallbacks(dojo.doc._results, dojo.doc._results);
},
functionPackage: function(/*Function*/ callback, /*Object*/ input){
dojo.debug("functionPackage() name: " + input.name + " for type: " + input.type);
input.type = "function_names";
input.callbacks.unshift(callback);
input.callbacks.unshift(dojo.doc._functionPackage);
dojo.doc._buildCache(input);
},
_functionPackage: function(/*String*/ type, /*Array*/ data, /*Object*/ evt){
dojo.debug("_functionPackage() name: " + evt.name + " for: " + evt.type + " with: " + type);
evt.pkg = '';
var data = dojo.doc._cache['function_names'];
for(var key in data){
if(dojo.lang.inArray(data[key], evt.name)){
evt.pkg = key;
break;
}
}
if(evt.callbacks && evt.callbacks.length){
var callback = evt.callbacks.shift();
callback.call(null, type, data[key], evt);
}
},
_sort: function(a, b){
if(a[0] < b[0]){
return -1;
}
if(a[0] > b[0]){
return 1;
}
return 0;
}
});
dojo.event.topic.subscribe("/doc/search", dojo.doc, "_onDocSearch");
dojo.event.topic.subscribe("/doc/selectFunction", dojo.doc, "_onDocSelectFunction");
dojo.event.topic.registerPublisher("/doc/results", dojo.doc, "_printResults");
dojo.event.topic.registerPublisher("/doc/functionDetail", dojo.doc, "_printFunctionDetail");

485
webapp/web/src/dom.js Normal file
View file

@ -0,0 +1,485 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.dom");
dojo.require("dojo.lang.array");
dojo.dom.ELEMENT_NODE = 1;
dojo.dom.ATTRIBUTE_NODE = 2;
dojo.dom.TEXT_NODE = 3;
dojo.dom.CDATA_SECTION_NODE = 4;
dojo.dom.ENTITY_REFERENCE_NODE = 5;
dojo.dom.ENTITY_NODE = 6;
dojo.dom.PROCESSING_INSTRUCTION_NODE = 7;
dojo.dom.COMMENT_NODE = 8;
dojo.dom.DOCUMENT_NODE = 9;
dojo.dom.DOCUMENT_TYPE_NODE = 10;
dojo.dom.DOCUMENT_FRAGMENT_NODE = 11;
dojo.dom.NOTATION_NODE = 12;
dojo.dom.dojoml = "http://www.dojotoolkit.org/2004/dojoml";
/**
* comprehensive list of XML namespaces
**/
dojo.dom.xmlns = {
svg : "http://www.w3.org/2000/svg",
smil : "http://www.w3.org/2001/SMIL20/",
mml : "http://www.w3.org/1998/Math/MathML",
cml : "http://www.xml-cml.org",
xlink : "http://www.w3.org/1999/xlink",
xhtml : "http://www.w3.org/1999/xhtml",
xul : "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
xbl : "http://www.mozilla.org/xbl",
fo : "http://www.w3.org/1999/XSL/Format",
xsl : "http://www.w3.org/1999/XSL/Transform",
xslt : "http://www.w3.org/1999/XSL/Transform",
xi : "http://www.w3.org/2001/XInclude",
xforms : "http://www.w3.org/2002/01/xforms",
saxon : "http://icl.com/saxon",
xalan : "http://xml.apache.org/xslt",
xsd : "http://www.w3.org/2001/XMLSchema",
dt: "http://www.w3.org/2001/XMLSchema-datatypes",
xsi : "http://www.w3.org/2001/XMLSchema-instance",
rdf : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
rdfs : "http://www.w3.org/2000/01/rdf-schema#",
dc : "http://purl.org/dc/elements/1.1/",
dcq: "http://purl.org/dc/qualifiers/1.0",
"soap-env" : "http://schemas.xmlsoap.org/soap/envelope/",
wsdl : "http://schemas.xmlsoap.org/wsdl/",
AdobeExtensions : "http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
};
dojo.dom.isNode = function(wh){
if(typeof Element == "object") {
try {
return wh instanceof Element;
} catch(E) {}
} else {
// best-guess
return wh && !isNaN(wh.nodeType);
}
}
dojo.dom.getTagName = function(node){
dojo.deprecated("dojo.dom.getTagName", "use node.tagName instead", "0.4");
var tagName = node.tagName;
if(tagName.substr(0,5).toLowerCase()!="dojo:"){
if(tagName.substr(0,4).toLowerCase()=="dojo"){
// FIXME: this assuumes tag names are always lower case
return "dojo:" + tagName.substring(4).toLowerCase();
}
// allow lower-casing
var djt = node.getAttribute("dojoType")||node.getAttribute("dojotype");
if(djt){
return "dojo:"+djt.toLowerCase();
}
if((node.getAttributeNS)&&(node.getAttributeNS(this.dojoml,"type"))){
return "dojo:" + node.getAttributeNS(this.dojoml,"type").toLowerCase();
}
try{
// FIXME: IE really really doesn't like this, so we squelch
// errors for it
djt = node.getAttribute("dojo:type");
}catch(e){ /* FIXME: log? */ }
if(djt){
return "dojo:"+djt.toLowerCase();
}
if((!dj_global["djConfig"])||(!djConfig["ignoreClassNames"])){
// FIXME: should we make this optionally enabled via djConfig?
var classes = node.className||node.getAttribute("class");
// FIXME: following line, without check for existence of classes.indexOf
// breaks firefox 1.5's svg widgets
if((classes)&&(classes.indexOf)&&(classes.indexOf("dojo-") != -1)){
var aclasses = classes.split(" ");
for(var x=0; x<aclasses.length; x++){
if((aclasses[x].length>5)&&(aclasses[x].indexOf("dojo-")>=0)){
return "dojo:"+aclasses[x].substr(5).toLowerCase();
}
}
}
}
}
return tagName.toLowerCase();
}
dojo.dom.getUniqueId = function(){
do {
var id = "dj_unique_" + (++arguments.callee._idIncrement);
}while(document.getElementById(id));
return id;
}
dojo.dom.getUniqueId._idIncrement = 0;
dojo.dom.firstElement = dojo.dom.getFirstChildElement = function(parentNode, tagName){
var node = parentNode.firstChild;
while(node && node.nodeType != dojo.dom.ELEMENT_NODE){
node = node.nextSibling;
}
if(tagName && node && node.tagName && node.tagName.toLowerCase() != tagName.toLowerCase()) {
node = dojo.dom.nextElement(node, tagName);
}
return node;
}
dojo.dom.lastElement = dojo.dom.getLastChildElement = function(parentNode, tagName){
var node = parentNode.lastChild;
while(node && node.nodeType != dojo.dom.ELEMENT_NODE) {
node = node.previousSibling;
}
if(tagName && node && node.tagName && node.tagName.toLowerCase() != tagName.toLowerCase()) {
node = dojo.dom.prevElement(node, tagName);
}
return node;
}
dojo.dom.nextElement = dojo.dom.getNextSiblingElement = function(node, tagName){
if(!node) { return null; }
do {
node = node.nextSibling;
} while(node && node.nodeType != dojo.dom.ELEMENT_NODE);
if(node && tagName && tagName.toLowerCase() != node.tagName.toLowerCase()) {
return dojo.dom.nextElement(node, tagName);
}
return node;
}
dojo.dom.prevElement = dojo.dom.getPreviousSiblingElement = function(node, tagName){
if(!node) { return null; }
if(tagName) { tagName = tagName.toLowerCase(); }
do {
node = node.previousSibling;
} while(node && node.nodeType != dojo.dom.ELEMENT_NODE);
if(node && tagName && tagName.toLowerCase() != node.tagName.toLowerCase()) {
return dojo.dom.prevElement(node, tagName);
}
return node;
}
// TODO: hmph
/*this.forEachChildTag = function(node, unaryFunc) {
var child = this.getFirstChildTag(node);
while(child) {
if(unaryFunc(child) == "break") { break; }
child = this.getNextSiblingTag(child);
}
}*/
dojo.dom.moveChildren = function(srcNode, destNode, trim){
var count = 0;
if(trim) {
while(srcNode.hasChildNodes() &&
srcNode.firstChild.nodeType == dojo.dom.TEXT_NODE) {
srcNode.removeChild(srcNode.firstChild);
}
while(srcNode.hasChildNodes() &&
srcNode.lastChild.nodeType == dojo.dom.TEXT_NODE) {
srcNode.removeChild(srcNode.lastChild);
}
}
while(srcNode.hasChildNodes()){
destNode.appendChild(srcNode.firstChild);
count++;
}
return count;
}
dojo.dom.copyChildren = function(srcNode, destNode, trim){
var clonedNode = srcNode.cloneNode(true);
return this.moveChildren(clonedNode, destNode, trim);
}
dojo.dom.removeChildren = function(node){
var count = node.childNodes.length;
while(node.hasChildNodes()){ node.removeChild(node.firstChild); }
return count;
}
dojo.dom.replaceChildren = function(node, newChild){
// FIXME: what if newChild is an array-like object?
dojo.dom.removeChildren(node);
node.appendChild(newChild);
}
dojo.dom.removeNode = function(node){
if(node && node.parentNode){
// return a ref to the removed child
return node.parentNode.removeChild(node);
}
}
dojo.dom.getAncestors = function(node, filterFunction, returnFirstHit) {
var ancestors = [];
var isFunction = dojo.lang.isFunction(filterFunction);
while(node) {
if (!isFunction || filterFunction(node)) {
ancestors.push(node);
}
if (returnFirstHit && ancestors.length > 0) { return ancestors[0]; }
node = node.parentNode;
}
if (returnFirstHit) { return null; }
return ancestors;
}
dojo.dom.getAncestorsByTag = function(node, tag, returnFirstHit) {
tag = tag.toLowerCase();
return dojo.dom.getAncestors(node, function(el){
return ((el.tagName)&&(el.tagName.toLowerCase() == tag));
}, returnFirstHit);
}
dojo.dom.getFirstAncestorByTag = function(node, tag) {
return dojo.dom.getAncestorsByTag(node, tag, true);
}
dojo.dom.isDescendantOf = function(node, ancestor, guaranteeDescendant){
// guaranteeDescendant allows us to be a "true" isDescendantOf function
if(guaranteeDescendant && node) { node = node.parentNode; }
while(node) {
if(node == ancestor){ return true; }
node = node.parentNode;
}
return false;
}
dojo.dom.innerXML = function(node){
if(node.innerXML){
return node.innerXML;
}else if (node.xml){
return node.xml;
}else if(typeof XMLSerializer != "undefined"){
return (new XMLSerializer()).serializeToString(node);
}
}
dojo.dom.createDocument = function(){
var doc = null;
if(!dj_undef("ActiveXObject")){
var prefixes = [ "MSXML2", "Microsoft", "MSXML", "MSXML3" ];
for(var i = 0; i<prefixes.length; i++){
try{
doc = new ActiveXObject(prefixes[i]+".XMLDOM");
}catch(e){ /* squelch */ };
if(doc){ break; }
}
}else if((document.implementation)&&
(document.implementation.createDocument)){
doc = document.implementation.createDocument("", "", null);
}
return doc;
}
dojo.dom.createDocumentFromText = function(str, mimetype){
if(!mimetype){ mimetype = "text/xml"; }
if(!dj_undef("DOMParser")){
var parser = new DOMParser();
return parser.parseFromString(str, mimetype);
}else if(!dj_undef("ActiveXObject")){
var domDoc = dojo.dom.createDocument();
if(domDoc){
domDoc.async = false;
domDoc.loadXML(str);
return domDoc;
}else{
dojo.debug("toXml didn't work?");
}
/*
}else if((dojo.render.html.capable)&&(dojo.render.html.safari)){
// FIXME: this doesn't appear to work!
// from: http://web-graphics.com/mtarchive/001606.php
// var xml = '<?xml version="1.0"?>'+str;
var mtype = "text/xml";
var xml = '<?xml version="1.0"?>'+str;
var url = "data:"+mtype+";charset=utf-8,"+encodeURIComponent(xml);
var req = new XMLHttpRequest();
req.open("GET", url, false);
req.overrideMimeType(mtype);
req.send(null);
return req.responseXML;
*/
}else if(document.createElement){
// FIXME: this may change all tags to uppercase!
var tmp = document.createElement("xml");
tmp.innerHTML = str;
if(document.implementation && document.implementation.createDocument) {
var xmlDoc = document.implementation.createDocument("foo", "", null);
for(var i = 0; i < tmp.childNodes.length; i++) {
xmlDoc.importNode(tmp.childNodes.item(i), true);
}
return xmlDoc;
}
// FIXME: probably not a good idea to have to return an HTML fragment
// FIXME: the tmp.doc.firstChild is as tested from IE, so it may not
// work that way across the board
return ((tmp.document)&&
(tmp.document.firstChild ? tmp.document.firstChild : tmp));
}
return null;
}
dojo.dom.prependChild = function(node, parent) {
if(parent.firstChild) {
parent.insertBefore(node, parent.firstChild);
} else {
parent.appendChild(node);
}
return true;
}
dojo.dom.insertBefore = function(node, ref, force){
if (force != true &&
(node === ref || node.nextSibling === ref)){ return false; }
var parent = ref.parentNode;
parent.insertBefore(node, ref);
return true;
}
dojo.dom.insertAfter = function(node, ref, force){
var pn = ref.parentNode;
if(ref == pn.lastChild){
if((force != true)&&(node === ref)){
return false;
}
pn.appendChild(node);
}else{
return this.insertBefore(node, ref.nextSibling, force);
}
return true;
}
dojo.dom.insertAtPosition = function(node, ref, position){
if((!node)||(!ref)||(!position)){ return false; }
switch(position.toLowerCase()){
case "before":
return dojo.dom.insertBefore(node, ref);
case "after":
return dojo.dom.insertAfter(node, ref);
case "first":
if(ref.firstChild){
return dojo.dom.insertBefore(node, ref.firstChild);
}else{
ref.appendChild(node);
return true;
}
break;
default: // aka: last
ref.appendChild(node);
return true;
}
}
dojo.dom.insertAtIndex = function(node, containingNode, insertionIndex){
var siblingNodes = containingNode.childNodes;
// if there aren't any kids yet, just add it to the beginning
if (!siblingNodes.length){
containingNode.appendChild(node);
return true;
}
// otherwise we need to walk the childNodes
// and find our spot
var after = null;
for(var i=0; i<siblingNodes.length; i++){
var sibling_index = siblingNodes.item(i)["getAttribute"] ? parseInt(siblingNodes.item(i).getAttribute("dojoinsertionindex")) : -1;
if (sibling_index < insertionIndex){
after = siblingNodes.item(i);
}
}
if (after){
// add it after the node in {after}
return dojo.dom.insertAfter(node, after);
}else{
// add it to the start
return dojo.dom.insertBefore(node, siblingNodes.item(0));
}
}
/**
* implementation of the DOM Level 3 attribute.
*
* @param node The node to scan for text
* @param text Optional, set the text to this value.
*/
dojo.dom.textContent = function(node, text){
if (text) {
dojo.dom.replaceChildren(node, document.createTextNode(text));
return text;
} else {
var _result = "";
if (node == null) { return _result; }
for (var i = 0; i < node.childNodes.length; i++) {
switch (node.childNodes[i].nodeType) {
case 1: // ELEMENT_NODE
case 5: // ENTITY_REFERENCE_NODE
_result += dojo.dom.textContent(node.childNodes[i]);
break;
case 3: // TEXT_NODE
case 2: // ATTRIBUTE_NODE
case 4: // CDATA_SECTION_NODE
_result += node.childNodes[i].nodeValue;
break;
default:
break;
}
}
return _result;
}
}
dojo.dom.collectionToArray = function(collection){
dojo.deprecated("dojo.dom.collectionToArray", "use dojo.lang.toArray instead", "0.4");
return dojo.lang.toArray(collection);
}
dojo.dom.hasParent = function (node) {
return node && node.parentNode && dojo.dom.isNode(node.parentNode);
}
/**
* Determines if node has any of the provided tag names and
* returns the tag name that matches, empty string otherwise.
*
* Examples:
*
* myFooNode = <foo />
* isTag(myFooNode, "foo"); // returns "foo"
* isTag(myFooNode, "bar"); // returns ""
* isTag(myFooNode, "FOO"); // returns ""
* isTag(myFooNode, "hey", "foo", "bar"); // returns "foo"
**/
dojo.dom.isTag = function(node /* ... */) {
if(node && node.tagName) {
var arr = dojo.lang.toArray(arguments, 1);
return arr[ dojo.lang.find(node.tagName, arr) ] || "";
}
return "";
}

575
webapp/web/src/event.js Normal file
View file

@ -0,0 +1,575 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.event");
dojo.require("dojo.lang.array");
dojo.require("dojo.lang.extras");
dojo.require("dojo.lang.func");
dojo.event = new function(){
this.canTimeout = dojo.lang.isFunction(dj_global["setTimeout"])||dojo.lang.isAlien(dj_global["setTimeout"]);
// FIXME: where should we put this method (not here!)?
function interpolateArgs(args, searchForNames){
var dl = dojo.lang;
var ao = {
srcObj: dj_global,
srcFunc: null,
adviceObj: dj_global,
adviceFunc: null,
aroundObj: null,
aroundFunc: null,
adviceType: (args.length>2) ? args[0] : "after",
precedence: "last",
once: false,
delay: null,
rate: 0,
adviceMsg: false
};
switch(args.length){
case 0: return;
case 1: return;
case 2:
ao.srcFunc = args[0];
ao.adviceFunc = args[1];
break;
case 3:
if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isString(args[2]))){
ao.adviceType = "after";
ao.srcObj = args[0];
ao.srcFunc = args[1];
ao.adviceFunc = args[2];
}else if((dl.isString(args[1]))&&(dl.isString(args[2]))){
ao.srcFunc = args[1];
ao.adviceFunc = args[2];
}else if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isFunction(args[2]))){
ao.adviceType = "after";
ao.srcObj = args[0];
ao.srcFunc = args[1];
var tmpName = dl.nameAnonFunc(args[2], ao.adviceObj, searchForNames);
ao.adviceFunc = tmpName;
}else if((dl.isFunction(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))){
ao.adviceType = "after";
ao.srcObj = dj_global;
var tmpName = dl.nameAnonFunc(args[0], ao.srcObj, searchForNames);
ao.srcFunc = tmpName;
ao.adviceObj = args[1];
ao.adviceFunc = args[2];
}
break;
case 4:
if((dl.isObject(args[0]))&&(dl.isObject(args[2]))){
// we can assume that we've got an old-style "connect" from
// the sigslot school of event attachment. We therefore
// assume after-advice.
ao.adviceType = "after";
ao.srcObj = args[0];
ao.srcFunc = args[1];
ao.adviceObj = args[2];
ao.adviceFunc = args[3];
}else if((dl.isString(args[0]))&&(dl.isString(args[1]))&&(dl.isObject(args[2]))){
ao.adviceType = args[0];
ao.srcObj = dj_global;
ao.srcFunc = args[1];
ao.adviceObj = args[2];
ao.adviceFunc = args[3];
}else if((dl.isString(args[0]))&&(dl.isFunction(args[1]))&&(dl.isObject(args[2]))){
ao.adviceType = args[0];
ao.srcObj = dj_global;
var tmpName = dl.nameAnonFunc(args[1], dj_global, searchForNames);
ao.srcFunc = tmpName;
ao.adviceObj = args[2];
ao.adviceFunc = args[3];
}else if((dl.isString(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))&&(dl.isFunction(args[3]))){
ao.srcObj = args[1];
ao.srcFunc = args[2];
var tmpName = dl.nameAnonFunc(args[3], dj_global, searchForNames);
ao.adviceObj = dj_global;
ao.adviceFunc = tmpName;
}else if(dl.isObject(args[1])){
ao.srcObj = args[1];
ao.srcFunc = args[2];
ao.adviceObj = dj_global;
ao.adviceFunc = args[3];
}else if(dl.isObject(args[2])){
ao.srcObj = dj_global;
ao.srcFunc = args[1];
ao.adviceObj = args[2];
ao.adviceFunc = args[3];
}else{
ao.srcObj = ao.adviceObj = ao.aroundObj = dj_global;
ao.srcFunc = args[1];
ao.adviceFunc = args[2];
ao.aroundFunc = args[3];
}
break;
case 6:
ao.srcObj = args[1];
ao.srcFunc = args[2];
ao.adviceObj = args[3]
ao.adviceFunc = args[4];
ao.aroundFunc = args[5];
ao.aroundObj = dj_global;
break;
default:
ao.srcObj = args[1];
ao.srcFunc = args[2];
ao.adviceObj = args[3]
ao.adviceFunc = args[4];
ao.aroundObj = args[5];
ao.aroundFunc = args[6];
ao.once = args[7];
ao.delay = args[8];
ao.rate = args[9];
ao.adviceMsg = args[10];
break;
}
if(dl.isFunction(ao.aroundFunc)){
var tmpName = dl.nameAnonFunc(ao.aroundFunc, ao.aroundObj, searchForNames);
ao.aroundFunc = tmpName;
}
if(dl.isFunction(ao.srcFunc)){
ao.srcFunc = dl.getNameInObj(ao.srcObj, ao.srcFunc);
}
if(dl.isFunction(ao.adviceFunc)){
ao.adviceFunc = dl.getNameInObj(ao.adviceObj, ao.adviceFunc);
}
if((ao.aroundObj)&&(dl.isFunction(ao.aroundFunc))){
ao.aroundFunc = dl.getNameInObj(ao.aroundObj, ao.aroundFunc);
}
if(!ao.srcObj){
dojo.raise("bad srcObj for srcFunc: "+ao.srcFunc);
}
if(!ao.adviceObj){
dojo.raise("bad adviceObj for adviceFunc: "+ao.adviceFunc);
}
return ao;
}
this.connect = function(){
if(arguments.length == 1){
var ao = arguments[0];
}else{
var ao = interpolateArgs(arguments, true);
}
if(dojo.lang.isArray(ao.srcObj) && ao.srcObj!=""){
var tmpAO = {};
for(var x in ao){
tmpAO[x] = ao[x];
}
var mjps = [];
dojo.lang.forEach(ao.srcObj, function(src){
if((dojo.render.html.capable)&&(dojo.lang.isString(src))){
src = dojo.byId(src);
// dojo.debug(src);
}
tmpAO.srcObj = src;
// dojo.debug(tmpAO.srcObj, tmpAO.srcFunc);
// dojo.debug(tmpAO.adviceObj, tmpAO.adviceFunc);
mjps.push(dojo.event.connect.call(dojo.event, tmpAO));
});
return mjps;
}
// FIXME: just doing a "getForMethod()" seems to be enough to put this into infinite recursion!!
var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc);
if(ao.adviceFunc){
var mjp2 = dojo.event.MethodJoinPoint.getForMethod(ao.adviceObj, ao.adviceFunc);
}
mjp.kwAddAdvice(ao);
return mjp; // advanced users might want to fsck w/ the join point
// manually
}
this.log = function(a1, a2){
var kwArgs;
if((arguments.length == 1)&&(typeof a1 == "object")){
kwArgs = a1;
}else{
kwArgs = {
srcObj: a1,
srcFunc: a2
};
}
kwArgs.adviceFunc = function(){
var argsStr = [];
for(var x=0; x<arguments.length; x++){
argsStr.push(arguments[x]);
}
dojo.debug("("+kwArgs.srcObj+")."+kwArgs.srcFunc, ":", argsStr.join(", "));
}
this.kwConnect(kwArgs);
}
this.connectBefore = function(){
var args = ["before"];
for(var i = 0; i < arguments.length; i++) { args.push(arguments[i]); }
return this.connect.apply(this, args);
}
this.connectAround = function(){
var args = ["around"];
for(var i = 0; i < arguments.length; i++) { args.push(arguments[i]); }
return this.connect.apply(this, args);
}
this.connectOnce = function(){
var ao = interpolateArgs(arguments, true);
ao.once = true;
return this.connect(ao);
}
this._kwConnectImpl = function(kwArgs, disconnect){
var fn = (disconnect) ? "disconnect" : "connect";
if(typeof kwArgs["srcFunc"] == "function"){
kwArgs.srcObj = kwArgs["srcObj"]||dj_global;
var tmpName = dojo.lang.nameAnonFunc(kwArgs.srcFunc, kwArgs.srcObj, true);
kwArgs.srcFunc = tmpName;
}
if(typeof kwArgs["adviceFunc"] == "function"){
kwArgs.adviceObj = kwArgs["adviceObj"]||dj_global;
var tmpName = dojo.lang.nameAnonFunc(kwArgs.adviceFunc, kwArgs.adviceObj, true);
kwArgs.adviceFunc = tmpName;
}
return dojo.event[fn]( (kwArgs["type"]||kwArgs["adviceType"]||"after"),
kwArgs["srcObj"]||dj_global,
kwArgs["srcFunc"],
kwArgs["adviceObj"]||kwArgs["targetObj"]||dj_global,
kwArgs["adviceFunc"]||kwArgs["targetFunc"],
kwArgs["aroundObj"],
kwArgs["aroundFunc"],
kwArgs["once"],
kwArgs["delay"],
kwArgs["rate"],
kwArgs["adviceMsg"]||false );
}
this.kwConnect = function(kwArgs){
return this._kwConnectImpl(kwArgs, false);
}
this.disconnect = function(){
var ao = interpolateArgs(arguments, true);
if(!ao.adviceFunc){ return; } // nothing to disconnect
var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc);
return mjp.removeAdvice(ao.adviceObj, ao.adviceFunc, ao.adviceType, ao.once);
}
this.kwDisconnect = function(kwArgs){
return this._kwConnectImpl(kwArgs, true);
}
}
// exactly one of these is created whenever a method with a joint point is run,
// if there is at least one 'around' advice.
dojo.event.MethodInvocation = function(join_point, obj, args) {
this.jp_ = join_point;
this.object = obj;
this.args = [];
for(var x=0; x<args.length; x++){
this.args[x] = args[x];
}
// the index of the 'around' that is currently being executed.
this.around_index = -1;
}
dojo.event.MethodInvocation.prototype.proceed = function() {
this.around_index++;
if(this.around_index >= this.jp_.around.length){
return this.jp_.object[this.jp_.methodname].apply(this.jp_.object, this.args);
// return this.jp_.run_before_after(this.object, this.args);
}else{
var ti = this.jp_.around[this.around_index];
var mobj = ti[0]||dj_global;
var meth = ti[1];
return mobj[meth].call(mobj, this);
}
}
dojo.event.MethodJoinPoint = function(obj, methname){
this.object = obj||dj_global;
this.methodname = methname;
this.methodfunc = this.object[methname];
this.before = [];
this.after = [];
this.around = [];
}
dojo.event.MethodJoinPoint.getForMethod = function(obj, methname) {
// if(!(methname in obj)){
if(!obj){ obj = dj_global; }
if(!obj[methname]){
// supply a do-nothing method implementation
obj[methname] = function(){};
if(!obj[methname]){
// e.g. cannot add to inbuilt objects in IE6
dojo.raise("Cannot set do-nothing method on that object "+methname);
}
}else if((!dojo.lang.isFunction(obj[methname]))&&(!dojo.lang.isAlien(obj[methname]))){
return null; // FIXME: should we throw an exception here instead?
}
// we hide our joinpoint instance in obj[methname + '$joinpoint']
var jpname = methname + "$joinpoint";
var jpfuncname = methname + "$joinpoint$method";
var joinpoint = obj[jpname];
if(!joinpoint){
var isNode = false;
if(dojo.event["browser"]){
if( (obj["attachEvent"])||
(obj["nodeType"])||
(obj["addEventListener"]) ){
isNode = true;
dojo.event.browser.addClobberNodeAttrs(obj, [jpname, jpfuncname, methname]);
}
}
var origArity = obj[methname].length;
obj[jpfuncname] = obj[methname];
// joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, methname);
joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, jpfuncname);
obj[methname] = function(){
var args = [];
if((isNode)&&(!arguments.length)){
var evt = null;
try{
if(obj.ownerDocument){
evt = obj.ownerDocument.parentWindow.event;
}else if(obj.documentElement){
evt = obj.documentElement.ownerDocument.parentWindow.event;
}else{
evt = window.event;
}
}catch(e){
evt = window.event;
}
if(evt){
args.push(dojo.event.browser.fixEvent(evt, this));
}
}else{
for(var x=0; x<arguments.length; x++){
if((x==0)&&(isNode)&&(dojo.event.browser.isEvent(arguments[x]))){
args.push(dojo.event.browser.fixEvent(arguments[x], this));
}else{
args.push(arguments[x]);
}
}
}
// return joinpoint.run.apply(joinpoint, arguments);
return joinpoint.run.apply(joinpoint, args);
}
obj[methname].__preJoinArity = origArity;
}
return joinpoint;
}
dojo.lang.extend(dojo.event.MethodJoinPoint, {
unintercept: function(){
this.object[this.methodname] = this.methodfunc;
this.before = [];
this.after = [];
this.around = [];
},
disconnect: dojo.lang.forward("unintercept"),
run: function() {
var obj = this.object||dj_global;
var args = arguments;
// optimization. We only compute once the array version of the arguments
// pseudo-arr in order to prevent building it each time advice is unrolled.
var aargs = [];
for(var x=0; x<args.length; x++){
aargs[x] = args[x];
}
var unrollAdvice = function(marr){
if(!marr){
dojo.debug("Null argument to unrollAdvice()");
return;
}
var callObj = marr[0]||dj_global;
var callFunc = marr[1];
if(!callObj[callFunc]){
dojo.raise("function \"" + callFunc + "\" does not exist on \"" + callObj + "\"");
}
var aroundObj = marr[2]||dj_global;
var aroundFunc = marr[3];
var msg = marr[6];
var undef;
var to = {
args: [],
jp_: this,
object: obj,
proceed: function(){
return callObj[callFunc].apply(callObj, to.args);
}
};
to.args = aargs;
var delay = parseInt(marr[4]);
var hasDelay = ((!isNaN(delay))&&(marr[4]!==null)&&(typeof marr[4] != "undefined"));
if(marr[5]){
var rate = parseInt(marr[5]);
var cur = new Date();
var timerSet = false;
if((marr["last"])&&((cur-marr.last)<=rate)){
if(dojo.event.canTimeout){
if(marr["delayTimer"]){
clearTimeout(marr.delayTimer);
}
var tod = parseInt(rate*2); // is rate*2 naive?
var mcpy = dojo.lang.shallowCopy(marr);
marr.delayTimer = setTimeout(function(){
// FIXME: on IE at least, event objects from the
// browser can go out of scope. How (or should?) we
// deal with it?
mcpy[5] = 0;
unrollAdvice(mcpy);
}, tod);
}
return;
}else{
marr.last = cur;
}
}
// FIXME: need to enforce rates for a connection here!
if(aroundFunc){
// NOTE: around advice can't delay since we might otherwise depend
// on execution order!
aroundObj[aroundFunc].call(aroundObj, to);
}else{
// var tmjp = dojo.event.MethodJoinPoint.getForMethod(obj, methname);
if((hasDelay)&&((dojo.render.html)||(dojo.render.svg))){ // FIXME: the render checks are grotty!
dj_global["setTimeout"](function(){
if(msg){
callObj[callFunc].call(callObj, to);
}else{
callObj[callFunc].apply(callObj, args);
}
}, delay);
}else{ // many environments can't support delay!
if(msg){
callObj[callFunc].call(callObj, to);
}else{
callObj[callFunc].apply(callObj, args);
}
}
}
}
if(this.before.length>0){
dojo.lang.forEach(this.before, unrollAdvice);
}
var result;
if(this.around.length>0){
var mi = new dojo.event.MethodInvocation(this, obj, args);
result = mi.proceed();
}else if(this.methodfunc){
result = this.object[this.methodname].apply(this.object, args);
}
if(this.after.length>0){
dojo.lang.forEach(this.after, unrollAdvice);
}
return (this.methodfunc) ? result : null;
},
getArr: function(kind){
var arr = this.after;
// FIXME: we should be able to do this through props or Array.in()
if((typeof kind == "string")&&(kind.indexOf("before")!=-1)){
arr = this.before;
}else if(kind=="around"){
arr = this.around;
}
return arr;
},
kwAddAdvice: function(args){
this.addAdvice( args["adviceObj"], args["adviceFunc"],
args["aroundObj"], args["aroundFunc"],
args["adviceType"], args["precedence"],
args["once"], args["delay"], args["rate"],
args["adviceMsg"]);
},
addAdvice: function( thisAdviceObj, thisAdvice,
thisAroundObj, thisAround,
advice_kind, precedence,
once, delay, rate, asMessage){
var arr = this.getArr(advice_kind);
if(!arr){
dojo.raise("bad this: " + this);
}
var ao = [thisAdviceObj, thisAdvice, thisAroundObj, thisAround, delay, rate, asMessage];
if(once){
if(this.hasAdvice(thisAdviceObj, thisAdvice, advice_kind, arr) >= 0){
return;
}
}
if(precedence == "first"){
arr.unshift(ao);
}else{
arr.push(ao);
}
},
hasAdvice: function(thisAdviceObj, thisAdvice, advice_kind, arr){
if(!arr){ arr = this.getArr(advice_kind); }
var ind = -1;
for(var x=0; x<arr.length; x++){
var aao = (typeof thisAdvice == "object") ? (new String(thisAdvice)).toString() : thisAdvice;
var a1o = (typeof arr[x][1] == "object") ? (new String(arr[x][1])).toString() : arr[x][1];
if((arr[x][0] == thisAdviceObj)&&(a1o == aao)){
ind = x;
}
}
return ind;
},
removeAdvice: function(thisAdviceObj, thisAdvice, advice_kind, once){
var arr = this.getArr(advice_kind);
var ind = this.hasAdvice(thisAdviceObj, thisAdvice, advice_kind, arr);
if(ind == -1){
return false;
}
while(ind != -1){
arr.splice(ind, 1);
if(once){ break; }
ind = this.hasAdvice(thisAdviceObj, thisAdvice, advice_kind, arr);
}
return true;
}
});

View file

@ -0,0 +1,16 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: ["dojo.event", "dojo.event.topic"],
browser: ["dojo.event.browser"],
dashboard: ["dojo.event.browser"]
});
dojo.provide("dojo.event.*");

View file

@ -0,0 +1,273 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.event.browser");
dojo.require("dojo.event");
// FIXME: any particular reason this is in the global scope?
dojo._ie_clobber = new function(){
this.clobberNodes = [];
function nukeProp(node, prop){
// try{ node.removeAttribute(prop); }catch(e){ /* squelch */ }
try{ node[prop] = null; }catch(e){ /* squelch */ }
try{ delete node[prop]; }catch(e){ /* squelch */ }
// FIXME: JotLive needs this, but I'm not sure if it's too slow or not
try{ node.removeAttribute(prop); }catch(e){ /* squelch */ }
}
this.clobber = function(nodeRef){
var na;
var tna;
if(nodeRef){
tna = nodeRef.all || nodeRef.getElementsByTagName("*");
na = [nodeRef];
for(var x=0; x<tna.length; x++){
// if we're gonna be clobbering the thing, at least make sure
// we aren't trying to do it twice
if(tna[x]["__doClobber__"]){
na.push(tna[x]);
}
}
}else{
try{ window.onload = null; }catch(e){}
na = (this.clobberNodes.length) ? this.clobberNodes : document.all;
}
tna = null;
var basis = {};
for(var i = na.length-1; i>=0; i=i-1){
var el = na[i];
if(el["__clobberAttrs__"]){
for(var j=0; j<el.__clobberAttrs__.length; j++){
nukeProp(el, el.__clobberAttrs__[j]);
}
nukeProp(el, "__clobberAttrs__");
nukeProp(el, "__doClobber__");
}
}
na = null;
}
}
if(dojo.render.html.ie){
dojo.addOnUnload(function(){
dojo._ie_clobber.clobber();
try{
if((dojo["widget"])&&(dojo.widget["manager"])){
dojo.widget.manager.destroyAll();
}
}catch(e){}
try{ window.onload = null; }catch(e){}
try{ window.onunload = null; }catch(e){}
dojo._ie_clobber.clobberNodes = [];
// CollectGarbage();
});
}
dojo.event.browser = new function(){
var clobberIdx = 0;
this.clean = function(node){
if(dojo.render.html.ie){
dojo._ie_clobber.clobber(node);
}
}
this.addClobberNode = function(node){
if(!dojo.render.html.ie){ return; }
if(!node["__doClobber__"]){
node.__doClobber__ = true;
dojo._ie_clobber.clobberNodes.push(node);
// this might not be the most efficient thing to do, but it's
// much less error prone than other approaches which were
// previously tried and failed
node.__clobberAttrs__ = [];
}
}
this.addClobberNodeAttrs = function(node, props){
if(!dojo.render.html.ie){ return; }
this.addClobberNode(node);
for(var x=0; x<props.length; x++){
node.__clobberAttrs__.push(props[x]);
}
}
this.removeListener = function(node, evtName, fp, capture){
if(!capture){ var capture = false; }
evtName = evtName.toLowerCase();
if(evtName.substr(0,2)=="on"){ evtName = evtName.substr(2); }
// FIXME: this is mostly a punt, we aren't actually doing anything on IE
if(node.removeEventListener){
node.removeEventListener(evtName, fp, capture);
}
}
this.addListener = function(node, evtName, fp, capture, dontFix){
if(!node){ return; } // FIXME: log and/or bail?
if(!capture){ var capture = false; }
evtName = evtName.toLowerCase();
if(evtName.substr(0,2)!="on"){ evtName = "on"+evtName; }
if(!dontFix){
// build yet another closure around fp in order to inject fixEvent
// around the resulting event
var newfp = function(evt){
if(!evt){ evt = window.event; }
var ret = fp(dojo.event.browser.fixEvent(evt, this));
if(capture){
dojo.event.browser.stopEvent(evt);
}
return ret;
}
}else{
newfp = fp;
}
if(node.addEventListener){
node.addEventListener(evtName.substr(2), newfp, capture);
return newfp;
}else{
if(typeof node[evtName] == "function" ){
var oldEvt = node[evtName];
node[evtName] = function(e){
oldEvt(e);
return newfp(e);
}
}else{
node[evtName]=newfp;
}
if(dojo.render.html.ie){
this.addClobberNodeAttrs(node, [evtName]);
}
return newfp;
}
}
this.isEvent = function(obj){
// FIXME: event detection hack ... could test for additional attributes
// if necessary
return (typeof obj != "undefined")&&(typeof Event != "undefined")&&(obj.eventPhase);
// Event does not support instanceof in Opera, otherwise:
//return (typeof Event != "undefined")&&(obj instanceof Event);
}
this.currentEvent = null;
this.callListener = function(listener, curTarget){
if(typeof listener != 'function'){
dojo.raise("listener not a function: " + listener);
}
dojo.event.browser.currentEvent.currentTarget = curTarget;
return listener.call(curTarget, dojo.event.browser.currentEvent);
}
this.stopPropagation = function(){
dojo.event.browser.currentEvent.cancelBubble = true;
}
this.preventDefault = function(){
dojo.event.browser.currentEvent.returnValue = false;
}
this.keys = {
KEY_BACKSPACE: 8,
KEY_TAB: 9,
KEY_ENTER: 13,
KEY_SHIFT: 16,
KEY_CTRL: 17,
KEY_ALT: 18,
KEY_PAUSE: 19,
KEY_CAPS_LOCK: 20,
KEY_ESCAPE: 27,
KEY_SPACE: 32,
KEY_PAGE_UP: 33,
KEY_PAGE_DOWN: 34,
KEY_END: 35,
KEY_HOME: 36,
KEY_LEFT_ARROW: 37,
KEY_UP_ARROW: 38,
KEY_RIGHT_ARROW: 39,
KEY_DOWN_ARROW: 40,
KEY_INSERT: 45,
KEY_DELETE: 46,
KEY_LEFT_WINDOW: 91,
KEY_RIGHT_WINDOW: 92,
KEY_SELECT: 93,
KEY_F1: 112,
KEY_F2: 113,
KEY_F3: 114,
KEY_F4: 115,
KEY_F5: 116,
KEY_F6: 117,
KEY_F7: 118,
KEY_F8: 119,
KEY_F9: 120,
KEY_F10: 121,
KEY_F11: 122,
KEY_F12: 123,
KEY_NUM_LOCK: 144,
KEY_SCROLL_LOCK: 145
};
// reverse lookup
this.revKeys = [];
for(var key in this.keys){
this.revKeys[this.keys[key]] = key;
}
this.fixEvent = function(evt, sender){
if((!evt)&&(window["event"])){
var evt = window.event;
}
if((evt["type"])&&(evt["type"].indexOf("key") == 0)){ // key events
evt.keys = this.revKeys;
// FIXME: how can we eliminate this iteration?
for(var key in this.keys) {
evt[key] = this.keys[key];
}
if((dojo.render.html.ie)&&(evt["type"] == "keypress")){
evt.charCode = evt.keyCode;
}
}
if(dojo.render.html.ie){
if(!evt.target){ evt.target = evt.srcElement; }
if(!evt.currentTarget){ evt.currentTarget = (sender ? sender : evt.srcElement); }
if(!evt.layerX){ evt.layerX = evt.offsetX; }
if(!evt.layerY){ evt.layerY = evt.offsetY; }
// FIXME: scroll position query is duped from dojo.html to avoid dependency on that entire module
var docBody = ((dojo.render.html.ie55)||(document["compatMode"] == "BackCompat")) ? document.body : document.documentElement;
if(!evt.pageX){ evt.pageX = evt.clientX + (docBody.scrollLeft || 0) }
if(!evt.pageY){ evt.pageY = evt.clientY + (docBody.scrollTop || 0) }
// mouseover
if(evt.type == "mouseover"){ evt.relatedTarget = evt.fromElement; }
// mouseout
if(evt.type == "mouseout"){ evt.relatedTarget = evt.toElement; }
this.currentEvent = evt;
evt.callListener = this.callListener;
evt.stopPropagation = this.stopPropagation;
evt.preventDefault = this.preventDefault;
}
return evt;
}
this.stopEvent = function(ev) {
if(window.event){
ev.returnValue = false;
ev.cancelBubble = true;
}else{
ev.preventDefault();
ev.stopPropagation();
}
}
}

View file

@ -0,0 +1,99 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.event");
dojo.provide("dojo.event.topic");
dojo.event.topic = new function(){
this.topics = {};
this.getTopic = function(topicName){
if(!this.topics[topicName]){
this.topics[topicName] = new this.TopicImpl(topicName);
}
return this.topics[topicName];
}
this.registerPublisher = function(topic, obj, funcName){
var topic = this.getTopic(topic);
topic.registerPublisher(obj, funcName);
}
this.subscribe = function(topic, obj, funcName){
var topic = this.getTopic(topic);
topic.subscribe(obj, funcName);
}
this.unsubscribe = function(topic, obj, funcName){
var topic = this.getTopic(topic);
topic.unsubscribe(obj, funcName);
}
this.destroy = function(topic){
this.getTopic(topic).destroy();
delete this.topics[topic];
}
this.publishApply = function(topic, args){
var topic = this.getTopic(topic);
topic.sendMessage.apply(topic, args);
}
this.publish = function(topic, message){
var topic = this.getTopic(topic);
// if message is an array, we treat it as a set of arguments,
// otherwise, we just pass on the arguments passed in as-is
var args = [];
// could we use concat instead here?
for(var x=1; x<arguments.length; x++){
args.push(arguments[x]);
}
topic.sendMessage.apply(topic, args);
}
}
dojo.event.topic.TopicImpl = function(topicName){
this.topicName = topicName;
this.subscribe = function(listenerObject, listenerMethod){
var tf = listenerMethod||listenerObject;
var to = (!listenerMethod) ? dj_global : listenerObject;
dojo.event.kwConnect({
srcObj: this,
srcFunc: "sendMessage",
adviceObj: to,
adviceFunc: tf
});
}
this.unsubscribe = function(listenerObject, listenerMethod){
var tf = (!listenerMethod) ? listenerObject : listenerMethod;
var to = (!listenerMethod) ? null : listenerObject;
dojo.event.kwDisconnect({
srcObj: this,
srcFunc: "sendMessage",
adviceObj: to,
adviceFunc: tf
});
}
this.destroy = function(){
dojo.event.MethodJoinPoint.getForMethod(this, "sendMessage").disconnect();
}
this.registerPublisher = function(publisherObject, publisherMethod){
dojo.event.connect(publisherObject, publisherMethod, this, "sendMessage");
}
this.sendMessage = function(message){
// The message has been propagated
}
}

View file

@ -0,0 +1,21 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.experimental");
/**
* Convenience for informing of experimental code.
*/
dojo.experimental = function(packageName, extra){
var mess = "EXPERIMENTAL: " + packageName;
mess += " -- Not yet ready for use. APIs subject to change without notice.";
if(extra){ mess += " " + extra; }
dojo.debug(mess);
}

1244
webapp/web/src/flash.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,214 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/**
An implementation of Flash 8's ExternalInterface that works with Flash 6
and which is source-compatible with Flash 8.
@author Brad Neuberg, bkn3@columbia.edu
*/
class DojoExternalInterface{
public static var available:Boolean;
public static var dojoPath = "";
public static var _fscommandReady = false;
public static var _callbacks = new Array();
public static function initialize(){
//getURL("javascript:dojo.debug('FLASH:DojoExternalInterface initialize')");
// FIXME: Set available variable by testing for capabilities
DojoExternalInterface.available = true;
// extract the dojo base path
DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();
//getURL("javascript:dojo.debug('FLASH:dojoPath="+DojoExternalInterface.dojoPath+"')");
// Sometimes, on IE, the fscommand infrastructure can take a few hundred
// milliseconds the first time a page loads. Set a timer to keep checking
// to make sure we can issue fscommands; otherwise, our calls to fscommand
// for setCallback() and loaded() will just "disappear"
_root.fscommandReady = false;
var fsChecker = function(){
// issue a test fscommand
fscommand("fscommandReady");
// JavaScript should set _root.fscommandReady if it got the call
if(_root.fscommandReady == "true"){
DojoExternalInterface._fscommandReady = true;
clearInterval(_root.fsTimer);
}
};
_root.fsTimer = setInterval(fsChecker, 100);
}
public static function addCallback(methodName:String, instance:Object,
method:Function) : Boolean{
// A variable that indicates whether the call below succeeded
_root._succeeded = null;
// Callbacks are registered with the JavaScript side as follows.
// On the Flash side, we maintain a lookup table that associates
// the methodName with the actual instance and method that are
// associated with this method.
// Using fscommand, we send over the action "addCallback", with the
// argument being the methodName to add, such as "foobar".
// The JavaScript takes these values and registers the existence of
// this callback point.
// precede the method name with a _ character in case it starts
// with a number
_callbacks["_" + methodName] = {_instance: instance, _method: method};
_callbacks[_callbacks.length] = methodName;
// The API for ExternalInterface says we have to make sure the call
// succeeded; check to see if there is a value
// for _succeeded, which is set by the JavaScript side
if(_root._succeeded == null){
return false;
}else{
return true;
}
}
public static function call(methodName:String,
resultsCallback:Function) : Void{
// FIXME: support full JSON serialization
// First, we pack up all of the arguments to this call and set them
// as Flash variables, which the JavaScript side will unpack using
// plugin.GetVariable(). We set the number of arguments as "_numArgs",
// and add each argument as a variable, such as "_1", "_2", etc., starting
// from 0.
// We then execute an fscommand with the action "call" and the
// argument being the method name. JavaScript takes the method name,
// retrieves the arguments using GetVariable, executes the method,
// and then places the return result in a Flash variable
// named "_returnResult".
_root._numArgs = arguments.length - 2;
for(var i = 2; i < arguments.length; i++){
var argIndex = i - 2;
_root["_" + argIndex] = arguments[i];
}
_root._returnResult = undefined;
fscommand("call", methodName);
// immediately return if the caller is not waiting for return results
if(resultsCallback == undefined || resultsCallback == null){
return;
}
// check at regular intervals for return results
var resultsChecker = function(){
if(_root._returnResult != undefined){
clearInterval(_root._callbackID);
resultsCallback.call(null, _root._returnResult);
}
};
_root._callbackID = setInterval(resultsChecker, 100);
}
/**
Called by Flash to indicate to JavaScript that we are ready to have
our Flash functions called. Calling loaded()
will fire the dojo.flash.loaded() event, so that JavaScript can know that
Flash has finished loading and adding its callbacks, and can begin to
interact with the Flash file.
*/
public static function loaded(){
//getURL("javascript:dojo.debug('FLASH:loaded')");
// one more step: see if fscommands are ready to be executed; if not,
// set an interval that will keep running until fscommands are ready;
// make sure the gateway is loaded as well
var execLoaded = function(){
if(DojoExternalInterface._fscommandReady == true){
clearInterval(_root.loadedInterval);
// initialize the small Flash file that helps gateway JS to Flash
// calls
DojoExternalInterface._initializeFlashRunner();
}
};
if(_fscommandReady == true){
execLoaded();
}else{
_root.loadedInterval = setInterval(execLoaded, 50);
}
}
/**
Handles and executes a JavaScript to Flash method call. Used by
initializeFlashRunner.
*/
public static function _handleJSCall(){
// get our parameters
var numArgs = parseInt(_root._numArgs);
var jsArgs = new Array();
for(var i = 0; i < numArgs; i++){
var currentValue = _root["_" + i];
jsArgs.push(currentValue);
}
// get our function name
var functionName = _root._functionName;
// now get the actual instance and method object to execute on,
// using our lookup table that was constructed by calls to
// addCallback on initialization
var instance = _callbacks["_" + functionName]._instance;
var method = _callbacks["_" + functionName]._method;
// execute it
var results = method.apply(instance, jsArgs);
// return the results
_root._returnResult = results;
}
/** Called by the flash6_gateway.swf to indicate that it is loaded. */
public static function _gatewayReady(){
for(var i = 0; i < _callbacks.length; i++){
fscommand("addCallback", _callbacks[i]);
}
call("dojo.flash.loaded");
}
/**
When JavaScript wants to communicate with Flash it simply sets
the Flash variable "_execute" to true; this method creates the
internal Movie Clip, called the Flash Runner, that makes this
magic happen.
*/
public static function _initializeFlashRunner(){
// figure out where our Flash movie is
var swfLoc = DojoExternalInterface.dojoPath + "flash6_gateway.swf";
// load our gateway helper file
_root.createEmptyMovieClip("_flashRunner", 5000);
_root._flashRunner._lockroot = true;
_root._flashRunner.loadMovie(swfLoc);
}
private static function getDojoPath(){
var url = _root._url;
var start = url.indexOf("baseRelativePath=") + "baseRelativePath=".length;
var path = url.substring(start);
var end = path.indexOf("&");
if(end != -1){
path = path.substring(0, end);
}
return path;
}
}
// vim:ts=4:noet:tw=0:

Binary file not shown.

View file

@ -0,0 +1,234 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/**
A wrapper around Flash 8's ExternalInterface; DojoExternalInterface is needed so that we
can do a Flash 6 implementation of ExternalInterface, and be able
to support having a single codebase that uses DojoExternalInterface
across Flash versions rather than having two seperate source bases,
where one uses ExternalInterface and the other uses DojoExternalInterface.
DojoExternalInterface class does a variety of optimizations to bypass ExternalInterface's
unbelievably bad performance so that we can have good performance
on Safari; see the blog post
http://codinginparadise.org/weblog/2006/02/how-to-speed-up-flash-8s.html
for details.
@author Brad Neuberg, bkn3@columbia.edu
*/
import flash.external.ExternalInterface;
class DojoExternalInterface{
public static var available:Boolean;
public static var dojoPath = "";
private static var flashMethods:Array = new Array();
private static var numArgs:Number;
private static var argData:Array;
private static var resultData = null;
public static function initialize(){
// extract the dojo base path
DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();
// see if we need to do an express install
var install:ExpressInstall = new ExpressInstall();
if(install.needsUpdate){
install.init();
}
// register our callback functions
ExternalInterface.addCallback("startExec", DojoExternalInterface, startExec);
ExternalInterface.addCallback("setNumberArguments", DojoExternalInterface,
setNumberArguments);
ExternalInterface.addCallback("chunkArgumentData", DojoExternalInterface,
chunkArgumentData);
ExternalInterface.addCallback("exec", DojoExternalInterface, exec);
ExternalInterface.addCallback("getReturnLength", DojoExternalInterface,
getReturnLength);
ExternalInterface.addCallback("chunkReturnData", DojoExternalInterface,
chunkReturnData);
ExternalInterface.addCallback("endExec", DojoExternalInterface, endExec);
// set whether communication is available
DojoExternalInterface.available = ExternalInterface.available;
DojoExternalInterface.call("loaded");
}
public static function addCallback(methodName:String, instance:Object,
method:Function) : Boolean{
// register DojoExternalInterface methodName with it's instance
DojoExternalInterface.flashMethods[methodName] = instance;
// tell JavaScript about DojoExternalInterface new method so we can create a proxy
ExternalInterface.call("dojo.flash.comm._addExternalInterfaceCallback",
methodName);
return true;
}
public static function call(methodName:String,
resultsCallback:Function) : Void{
// we might have any number of optional arguments, so we have to
// pass them in dynamically; strip out the results callback
var parameters = new Array();
for(var i = 0; i < arguments.length; i++){
if(i != 1){ // skip the callback
parameters.push(arguments[i]);
}
}
var results = ExternalInterface.call.apply(ExternalInterface, parameters);
// immediately give the results back, since ExternalInterface is
// synchronous
if(resultsCallback != null && typeof resultsCallback != "undefined"){
resultsCallback.call(null, results);
}
}
/**
Called by Flash to indicate to JavaScript that we are ready to have
our Flash functions called. Calling loaded()
will fire the dojo.flash.loaded() event, so that JavaScript can know that
Flash has finished loading and adding its callbacks, and can begin to
interact with the Flash file.
*/
public static function loaded(){
DojoExternalInterface.call("dojo.flash.loaded");
}
public static function startExec():Void{
DojoExternalInterface.numArgs = null;
DojoExternalInterface.argData = null;
DojoExternalInterface.resultData = null;
}
public static function setNumberArguments(numArgs):Void{
DojoExternalInterface.numArgs = numArgs;
DojoExternalInterface.argData = new Array(DojoExternalInterface.numArgs);
}
public static function chunkArgumentData(value, argIndex:Number):Void{
//getURL("javascript:dojo.debug('FLASH: chunkArgumentData, value="+value+", argIndex="+argIndex+"')");
var currentValue = DojoExternalInterface.argData[argIndex];
if(currentValue == null || typeof currentValue == "undefined"){
DojoExternalInterface.argData[argIndex] = value;
}else{
DojoExternalInterface.argData[argIndex] += value;
}
}
public static function exec(methodName):Void{
// decode all of the arguments that were passed in
for(var i = 0; i < DojoExternalInterface.argData.length; i++){
DojoExternalInterface.argData[i] =
DojoExternalInterface.decodeData(DojoExternalInterface.argData[i]);
}
var instance = DojoExternalInterface.flashMethods[methodName];
DojoExternalInterface.resultData = instance[methodName].apply(
instance, DojoExternalInterface.argData);
// encode the result data
DojoExternalInterface.resultData =
DojoExternalInterface.encodeData(DojoExternalInterface.resultData);
//getURL("javascript:dojo.debug('FLASH: encoded result data="+DojoExternalInterface.resultData+"')");
}
public static function getReturnLength():Number{
if(DojoExternalInterface.resultData == null ||
typeof DojoExternalInterface.resultData == "undefined"){
return 0;
}
var segments = Math.ceil(DojoExternalInterface.resultData.length / 1024);
return segments;
}
public static function chunkReturnData(segment:Number):String{
var numSegments = DojoExternalInterface.getReturnLength();
var startCut = segment * 1024;
var endCut = segment * 1024 + 1024;
if(segment == (numSegments - 1)){
endCut = segment * 1024 + DojoExternalInterface.resultData.length;
}
var piece = DojoExternalInterface.resultData.substring(startCut, endCut);
//getURL("javascript:dojo.debug('FLASH: chunking return piece="+piece+"')");
return piece;
}
public static function endExec():Void{
}
private static function decodeData(data):String{
// we have to use custom encodings for certain characters when passing
// them over; for example, passing a backslash over as //// from JavaScript
// to Flash doesn't work
data = DojoExternalInterface.replaceStr(data, "&custom_backslash;", "\\");
data = DojoExternalInterface.replaceStr(data, "\\\'", "\'");
data = DojoExternalInterface.replaceStr(data, "\\\"", "\"");
return data;
}
private static function encodeData(data){
//getURL("javascript:dojo.debug('inside flash, data before="+data+"')");
// double encode all entity values, or they will be mis-decoded
// by Flash when returned
data = DojoExternalInterface.replaceStr(data, "&", "&amp;");
// certain XMLish characters break Flash's wire serialization for
// ExternalInterface; encode these into a custom encoding, rather than
// the standard entity encoding, because otherwise we won't be able to
// differentiate between our own encoding and any entity characters
// that are being used in the string itself
data = DojoExternalInterface.replaceStr(data, '<', '&custom_lt;');
data = DojoExternalInterface.replaceStr(data, '>', '&custom_gt;');
// encode control characters and JavaScript delimiters
data = DojoExternalInterface.replaceStr(data, "\n", "\\n");
data = DojoExternalInterface.replaceStr(data, "\r", "\\r");
data = DojoExternalInterface.replaceStr(data, "\f", "\\f");
data = DojoExternalInterface.replaceStr(data, "'", "\\'");
data = DojoExternalInterface.replaceStr(data, '"', '\"');
//getURL("javascript:dojo.debug('inside flash, data after="+data+"')");
return data;
}
/**
Flash ActionScript has no String.replace method or support for
Regular Expressions! We roll our own very simple one.
*/
private static function replaceStr(inputStr:String, replaceThis:String,
withThis:String):String {
var splitStr = inputStr.split(replaceThis)
inputStr = splitStr.join(withThis)
return inputStr;
}
private static function getDojoPath(){
var url = _root._url;
var start = url.indexOf("baseRelativePath=") + "baseRelativePath=".length;
var path = url.substring(start);
var end = path.indexOf("&");
if(end != -1){
path = path.substring(0, end);
}
return path;
}
}
// vim:ts=4:noet:tw=0:

View file

@ -0,0 +1,81 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/**
* Based on the expressinstall.as class created by Geoff Stearns as part
* of the FlashObject library.
*
* Use this file to invoke the Macromedia Flash Player Express Install functionality
* This file is intended for use with the FlashObject embed script. You can download FlashObject
* and this file at the following URL: http://blog.deconcept.com/flashobject/
*
* Usage:
* var ExpressInstall = new ExpressInstall();
*
* // test to see if install is needed:
* if (ExpressInstall.needsUpdate) { // returns true if update is needed
* ExpressInstall.init(); // starts the update
* }
*
* NOTE: Your Flash movie must be at least 214px by 137px in order to use ExpressInstall.
*
*/
class ExpressInstall {
public var needsUpdate:Boolean;
private var updater:MovieClip;
private var hold:MovieClip;
public function ExpressInstall(){
// does the user need to update?
this.needsUpdate = (_root.MMplayerType == undefined) ? false : true;
}
public function init():Void{
this.loadUpdater();
}
public function loadUpdater():Void {
System.security.allowDomain("fpdownload.macromedia.com");
// hope that nothing is at a depth of 10000000, you can change this depth if needed, but you want
// it to be on top of your content if you have any stuff on the first frame
this.updater = _root.createEmptyMovieClip("expressInstallHolder", 10000000);
// register the callback so we know if they cancel or there is an error
var _self = this;
this.updater.installStatus = _self.onInstallStatus;
this.hold = this.updater.createEmptyMovieClip("hold", 1);
// can't use movieClipLoader because it has to work in 6.0.65
this.updater.onEnterFrame = function():Void {
if(typeof this.hold.startUpdate == 'function'){
_self.initUpdater();
this.onEnterFrame = null;
}
}
var cacheBuster:Number = Math.random();
this.hold.loadMovie("http://fpdownload.macromedia.com/pub/flashplayer/"
+"update/current/swf/autoUpdater.swf?"+ cacheBuster);
}
private function initUpdater():Void{
this.hold.redirectURL = _root.MMredirectURL;
this.hold.MMplayerType = _root.MMplayerType;
this.hold.MMdoctitle = _root.MMdoctitle;
this.hold.startUpdate();
}
public function onInstallStatus(msg):Void{
getURL("javascript:dojo.flash.install._onInstallStatus('"+msg+"')");
}
}

View file

@ -0,0 +1,15 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
browser: ["dojo.fx.html"],
dashboard: ["dojo.fx.html"]
});
dojo.provide("dojo.fx.*");

573
webapp/web/src/fx/html.js Normal file
View file

@ -0,0 +1,573 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.fx.html");
dojo.require("dojo.style");
dojo.require("dojo.math.curves");
dojo.require("dojo.lang.func");
dojo.require("dojo.animation");
dojo.require("dojo.event.*");
dojo.require("dojo.graphics.color");
dojo.deprecated("dojo.fx.html", "use dojo.lfx.html instead", "0.4");
dojo.fx.duration = 300;
dojo.fx.html._makeFadeable = function(node){
if(dojo.render.html.ie){
// only set the zoom if the "tickle" value would be the same as the
// default
if( (node.style.zoom.length == 0) &&
(dojo.style.getStyle(node, "zoom") == "normal") ){
// make sure the node "hasLayout"
// NOTE: this has been tested with larger and smaller user-set text
// sizes and works fine
node.style.zoom = "1";
// node.style.zoom = "normal";
}
// don't set the width to auto if it didn't already cascade that way.
// We don't want to f anyones designs
if( (node.style.width.length == 0) &&
(dojo.style.getStyle(node, "width") == "auto") ){
node.style.width = "auto";
}
}
}
dojo.fx.html.fadeOut = function(node, duration, callback, dontPlay) {
return dojo.fx.html.fade(node, duration, dojo.style.getOpacity(node), 0, callback, dontPlay);
};
dojo.fx.html.fadeIn = function(node, duration, callback, dontPlay) {
return dojo.fx.html.fade(node, duration, dojo.style.getOpacity(node), 1, callback, dontPlay);
};
dojo.fx.html.fadeHide = function(node, duration, callback, dontPlay) {
node = dojo.byId(node);
if(!duration) { duration = 150; } // why not have a default?
return dojo.fx.html.fadeOut(node, duration, function(node) {
node.style.display = "none";
if(typeof callback == "function") { callback(node); }
});
};
dojo.fx.html.fadeShow = function(node, duration, callback, dontPlay) {
node = dojo.byId(node);
if(!duration) { duration = 150; } // why not have a default?
node.style.display = "block";
return dojo.fx.html.fade(node, duration, 0, 1, callback, dontPlay);
};
dojo.fx.html.fade = function(node, duration, startOpac, endOpac, callback, dontPlay) {
node = dojo.byId(node);
dojo.fx.html._makeFadeable(node);
var anim = new dojo.animation.Animation(
new dojo.math.curves.Line([startOpac],[endOpac]),
duration||dojo.fx.duration, 0);
dojo.event.connect(anim, "onAnimate", function(e) {
dojo.style.setOpacity(node, e.x);
});
if(callback) {
dojo.event.connect(anim, "onEnd", function(e) {
callback(node, anim);
});
}
if(!dontPlay) { anim.play(true); }
return anim;
};
dojo.fx.html.slideTo = function(node, duration, endCoords, callback, dontPlay) {
if(!dojo.lang.isNumber(duration)) {
var tmp = duration;
duration = endCoords;
endCoords = tmp;
}
node = dojo.byId(node);
var top = node.offsetTop;
var left = node.offsetLeft;
var pos = dojo.style.getComputedStyle(node, 'position');
if (pos == 'relative' || pos == 'static') {
top = parseInt(dojo.style.getComputedStyle(node, 'top')) || 0;
left = parseInt(dojo.style.getComputedStyle(node, 'left')) || 0;
}
return dojo.fx.html.slide(node, duration, [left, top],
endCoords, callback, dontPlay);
};
dojo.fx.html.slideBy = function(node, duration, coords, callback, dontPlay) {
if(!dojo.lang.isNumber(duration)) {
var tmp = duration;
duration = coords;
coords = tmp;
}
node = dojo.byId(node);
var top = node.offsetTop;
var left = node.offsetLeft;
var pos = dojo.style.getComputedStyle(node, 'position');
if (pos == 'relative' || pos == 'static') {
top = parseInt(dojo.style.getComputedStyle(node, 'top')) || 0;
left = parseInt(dojo.style.getComputedStyle(node, 'left')) || 0;
}
return dojo.fx.html.slideTo(node, duration, [left+coords[0], top+coords[1]],
callback, dontPlay);
};
dojo.fx.html.slide = function(node, duration, startCoords, endCoords, callback, dontPlay) {
if(!dojo.lang.isNumber(duration)) {
var tmp = duration;
duration = endCoords;
endCoords = startCoords;
startCoords = tmp;
}
node = dojo.byId(node);
if (dojo.style.getComputedStyle(node, 'position') == 'static') {
node.style.position = 'relative';
}
var anim = new dojo.animation.Animation(
new dojo.math.curves.Line(startCoords, endCoords),
duration||dojo.fx.duration, 0);
dojo.event.connect(anim, "onAnimate", function(e) {
with( node.style ) {
left = e.x + "px";
top = e.y + "px";
}
});
if(callback) {
dojo.event.connect(anim, "onEnd", function(e) {
callback(node, anim);
});
}
if(!dontPlay) { anim.play(true); }
return anim;
};
// Fade from startColor to the node's background color
dojo.fx.html.colorFadeIn = function(node, duration, startColor, delay, callback, dontPlay) {
if(!dojo.lang.isNumber(duration)) {
var tmp = duration;
duration = startColor;
startColor = tmp;
}
node = dojo.byId(node);
var color = dojo.style.getBackgroundColor(node);
var bg = dojo.style.getStyle(node, "background-color").toLowerCase();
var wasTransparent = bg == "transparent" || bg == "rgba(0, 0, 0, 0)";
while(color.length > 3) { color.pop(); }
var rgb = new dojo.graphics.color.Color(startColor).toRgb();
var anim = dojo.fx.html.colorFade(node, duration||dojo.fx.duration, startColor, color, callback, true);
dojo.event.connect(anim, "onEnd", function(e) {
if( wasTransparent ) {
node.style.backgroundColor = "transparent";
}
});
if( delay > 0 ) {
node.style.backgroundColor = "rgb(" + rgb.join(",") + ")";
if(!dontPlay) { setTimeout(function(){anim.play(true)}, delay); }
} else {
if(!dontPlay) { anim.play(true); }
}
return anim;
};
// alias for (probably?) common use/terminology
dojo.fx.html.highlight = dojo.fx.html.colorFadeIn;
dojo.fx.html.colorFadeFrom = dojo.fx.html.colorFadeIn;
// Fade from node's background color to endColor
dojo.fx.html.colorFadeOut = function(node, duration, endColor, delay, callback, dontPlay) {
if(!dojo.lang.isNumber(duration)) {
var tmp = duration;
duration = endColor;
endColor = tmp;
}
node = dojo.byId(node);
var color = new dojo.graphics.color.Color(dojo.style.getBackgroundColor(node)).toRgb();
var rgb = new dojo.graphics.color.Color(endColor).toRgb();
var anim = dojo.fx.html.colorFade(node, duration||dojo.fx.duration, color, rgb, callback, delay > 0 || dontPlay);
if( delay > 0 ) {
node.style.backgroundColor = "rgb(" + color.join(",") + ")";
if(!dontPlay) { setTimeout(function(){anim.play(true)}, delay); }
}
return anim;
};
// FIXME: not sure which name is better. an alias here may be bad.
dojo.fx.html.unhighlight = dojo.fx.html.colorFadeOut;
dojo.fx.html.colorFadeTo = dojo.fx.html.colorFadeOut;
// Fade node background from startColor to endColor
dojo.fx.html.colorFade = function(node, duration, startColor, endColor, callback, dontPlay) {
if(!dojo.lang.isNumber(duration)) {
var tmp = duration;
duration = endColor;
endColor = startColor;
startColor = tmp;
}
node = dojo.byId(node);
var startRgb = new dojo.graphics.color.Color(startColor).toRgb();
var endRgb = new dojo.graphics.color.Color(endColor).toRgb();
var anim = new dojo.animation.Animation(
new dojo.math.curves.Line(startRgb, endRgb),
duration||dojo.fx.duration, 0);
dojo.event.connect(anim, "onAnimate", function(e) {
node.style.backgroundColor = "rgb(" + e.coordsAsInts().join(",") + ")";
});
if(callback) {
dojo.event.connect(anim, "onEnd", function(e) {
callback(node, anim);
});
}
if( !dontPlay ) { anim.play(true); }
return anim;
};
dojo.fx.html.wipeIn = function(node, duration, callback, dontPlay) {
node = dojo.byId(node);
var overflow = dojo.style.getStyle(node, "overflow");
if(overflow == "visible") {
node.style.overflow = "hidden";
}
node.style.height = 0;
dojo.style.show(node);
var anim = dojo.fx.html.wipe(node, duration, 0, node.scrollHeight, null, true);
dojo.event.connect(anim, "onEnd", function() {
node.style.overflow = overflow;
node.style.visibility = "";
node.style.height = "auto";
if(callback) { callback(node, anim); }
});
if(!dontPlay) { anim.play(); }
return anim;
}
dojo.fx.html.wipeOut = function(node, duration, callback, dontPlay) {
node = dojo.byId(node);
var overflow = dojo.style.getStyle(node, "overflow");
if(overflow == "visible") {
node.style.overflow = "hidden";
}
var anim = dojo.fx.html.wipe(node, duration, node.offsetHeight, 0, null, true);
dojo.event.connect(anim, "onEnd", function() {
dojo.style.hide(node);
node.style.visibility = "hidden";
node.style.overflow = overflow;
if(callback) { callback(node, anim); }
});
if(!dontPlay) { anim.play(); }
return anim;
}
dojo.fx.html.wipe = function(node, duration, startHeight, endHeight, callback, dontPlay) {
node = dojo.byId(node);
var anim = new dojo.animation.Animation([[startHeight], [endHeight]], duration||dojo.fx.duration, 0);
dojo.event.connect(anim, "onAnimate", function(e) {
node.style.height = e.x + "px";
});
dojo.event.connect(anim, "onEnd", function() {
if(callback) { callback(node, anim); }
});
if(!dontPlay) { anim.play(); }
return anim;
}
dojo.fx.html.wiper = function(node, controlNode) {
this.node = dojo.byId(node);
if(controlNode) {
dojo.event.connect(dojo.byId(controlNode), "onclick", this, "toggle");
}
}
dojo.lang.extend(dojo.fx.html.wiper, {
duration: dojo.fx.duration,
_anim: null,
toggle: function() {
if(!this._anim) {
var type = "wipe" + (dojo.style.isVisible(this.node) ? "Out" : "In");
this._anim = dojo.fx[type](this.node, this.duration, dojo.lang.hitch(this, "_callback"));
}
},
_callback: function() {
this._anim = null;
}
});
dojo.fx.html.explode = function(start, endNode, duration, callback, dontPlay) {
var startCoords = dojo.style.toCoordinateArray(start);
var outline = document.createElement("div");
with(outline.style) {
position = "absolute";
border = "1px solid black";
display = "none";
}
document.body.appendChild(outline);
endNode = dojo.byId(endNode);
with(endNode.style) {
visibility = "hidden";
display = "block";
}
var endCoords = dojo.style.toCoordinateArray(endNode);
with(endNode.style) {
display = "none";
visibility = "visible";
}
var anim = new dojo.animation.Animation(
new dojo.math.curves.Line(startCoords, endCoords),
duration||dojo.fx.duration, 0
);
dojo.event.connect(anim, "onBegin", function(e) {
outline.style.display = "block";
});
dojo.event.connect(anim, "onAnimate", function(e) {
with(outline.style) {
left = e.x + "px";
top = e.y + "px";
width = e.coords[2] + "px";
height = e.coords[3] + "px";
}
});
dojo.event.connect(anim, "onEnd", function() {
endNode.style.display = "block";
outline.parentNode.removeChild(outline);
if(callback) { callback(endNode, anim); }
});
if(!dontPlay) { anim.play(); }
return anim;
};
dojo.fx.html.implode = function(startNode, end, duration, callback, dontPlay) {
var startCoords = dojo.style.toCoordinateArray(startNode);
var endCoords = dojo.style.toCoordinateArray(end);
startNode = dojo.byId(startNode);
var outline = document.createElement("div");
with(outline.style) {
position = "absolute";
border = "1px solid black";
display = "none";
}
document.body.appendChild(outline);
var anim = new dojo.animation.Animation(
new dojo.math.curves.Line(startCoords, endCoords),
duration||dojo.fx.duration, 0
);
dojo.event.connect(anim, "onBegin", function(e) {
startNode.style.display = "none";
outline.style.display = "block";
});
dojo.event.connect(anim, "onAnimate", function(e) {
with(outline.style) {
left = e.x + "px";
top = e.y + "px";
width = e.coords[2] + "px";
height = e.coords[3] + "px";
}
});
dojo.event.connect(anim, "onEnd", function() {
outline.parentNode.removeChild(outline);
if(callback) { callback(startNode, anim); }
});
if(!dontPlay) { anim.play(); }
return anim;
};
dojo.fx.html.Exploder = function(triggerNode, boxNode) {
triggerNode = dojo.byId(triggerNode);
boxNode = dojo.byId(boxNode);
var _this = this;
// custom options
this.waitToHide = 500;
this.timeToShow = 100;
this.waitToShow = 200;
this.timeToHide = 70;
this.autoShow = false;
this.autoHide = false;
var animShow = null;
var animHide = null;
var showTimer = null;
var hideTimer = null;
var startCoords = null;
var endCoords = null;
this.showing = false;
this.onBeforeExplode = null;
this.onAfterExplode = null;
this.onBeforeImplode = null;
this.onAfterImplode = null;
this.onExploding = null;
this.onImploding = null;
this.timeShow = function() {
clearTimeout(showTimer);
showTimer = setTimeout(_this.show, _this.waitToShow);
}
this.show = function() {
clearTimeout(showTimer);
clearTimeout(hideTimer);
//triggerNode.blur();
if( (animHide && animHide.status() == "playing")
|| (animShow && animShow.status() == "playing")
|| _this.showing ) { return; }
if(typeof _this.onBeforeExplode == "function") { _this.onBeforeExplode(triggerNode, boxNode); }
animShow = dojo.fx.html.explode(triggerNode, boxNode, _this.timeToShow, function(e) {
_this.showing = true;
if(typeof _this.onAfterExplode == "function") { _this.onAfterExplode(triggerNode, boxNode); }
});
if(typeof _this.onExploding == "function") {
dojo.event.connect(animShow, "onAnimate", this, "onExploding");
}
}
this.timeHide = function() {
clearTimeout(showTimer);
clearTimeout(hideTimer);
if(_this.showing) {
hideTimer = setTimeout(_this.hide, _this.waitToHide);
}
}
this.hide = function() {
clearTimeout(showTimer);
clearTimeout(hideTimer);
if( animShow && animShow.status() == "playing" ) {
return;
}
_this.showing = false;
if(typeof _this.onBeforeImplode == "function") { _this.onBeforeImplode(triggerNode, boxNode); }
animHide = dojo.fx.html.implode(boxNode, triggerNode, _this.timeToHide, function(e){
if(typeof _this.onAfterImplode == "function") { _this.onAfterImplode(triggerNode, boxNode); }
});
if(typeof _this.onImploding == "function") {
dojo.event.connect(animHide, "onAnimate", this, "onImploding");
}
}
// trigger events
dojo.event.connect(triggerNode, "onclick", function(e) {
if(_this.showing) {
_this.hide();
} else {
_this.show();
}
});
dojo.event.connect(triggerNode, "onmouseover", function(e) {
if(_this.autoShow) {
_this.timeShow();
}
});
dojo.event.connect(triggerNode, "onmouseout", function(e) {
if(_this.autoHide) {
_this.timeHide();
}
});
// box events
dojo.event.connect(boxNode, "onmouseover", function(e) {
clearTimeout(hideTimer);
});
dojo.event.connect(boxNode, "onmouseout", function(e) {
if(_this.autoHide) {
_this.timeHide();
}
});
// document events
dojo.event.connect(document.documentElement || document.body, "onclick", function(e) {
function isDesc(node, ancestor) {
while(node) {
if(node == ancestor){ return true; }
node = node.parentNode;
}
return false;
}
if(_this.autoHide && _this.showing
&& !isDesc(e.target, boxNode)
&& !isDesc(e.target, triggerNode) ) {
_this.hide();
}
});
return this;
};
/****
Strategies for displaying/hiding objects
This presents a standard interface for each of the effects
*****/
dojo.fx.html.toggle={}
dojo.fx.html.toggle.plain = {
show: function(node, duration, explodeSrc, callback){
dojo.style.show(node);
if(dojo.lang.isFunction(callback)){ callback(); }
},
hide: function(node, duration, explodeSrc, callback){
dojo.style.hide(node);
if(dojo.lang.isFunction(callback)){ callback(); }
}
}
dojo.fx.html.toggle.fade = {
show: function(node, duration, explodeSrc, callback){
dojo.fx.html.fadeShow(node, duration, callback);
},
hide: function(node, duration, explodeSrc, callback){
dojo.fx.html.fadeHide(node, duration, callback);
}
}
dojo.fx.html.toggle.wipe = {
show: function(node, duration, explodeSrc, callback){
dojo.fx.html.wipeIn(node, duration, callback);
},
hide: function(node, duration, explodeSrc, callback){
dojo.fx.html.wipeOut(node, duration, callback);
}
}
dojo.fx.html.toggle.explode = {
show: function(node, duration, explodeSrc, callback){
dojo.fx.html.explode(explodeSrc||[0,0,0,0], node, duration, callback);
},
hide: function(node, duration, explodeSrc, callback){
dojo.fx.html.implode(node, explodeSrc||[0,0,0,0], duration, callback);
}
}
dojo.lang.mixin(dojo.fx, dojo.fx.html);

99
webapp/web/src/fx/svg.js Normal file
View file

@ -0,0 +1,99 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.fx.svg");
dojo.require("dojo.svg");
dojo.require("dojo.animation.*");
dojo.require("dojo.event.*");
dojo.fx.svg.fadeOut = function(node, duration, callback){
return dojo.fx.svg.fade(node, duration, dojo.svg.getOpacity(node), 0, callback);
};
dojo.fx.svg.fadeIn = function(node, duration, callback){
return dojo.fx.svg.fade(node, duration, dojo.svg.getOpacity(node), 1, callback);
};
dojo.fx.svg.fadeHide = function(node, duration, callback){
if(!duration) { duration = 150; } // why not have a default?
return dojo.fx.svg.fadeOut(node, duration, function(node) {
if(typeof callback == "function") { callback(node); }
});
};
dojo.fx.svg.fadeShow = function(node, duration, callback){
if(!duration) { duration = 150; } // why not have a default?
return dojo.fx.svg.fade(node, duration, 0, 1, callback);
};
dojo.fx.svg.fade = function(node, duration, startOpac, endOpac, callback){
var anim = new dojo.animation.Animation(
new dojo.math.curves.Line([startOpac],[endOpac]),
duration,
0
);
dojo.event.connect(anim, "onAnimate", function(e){
dojo.svg.setOpacity(node, e.x);
});
if (callback) {
dojo.event.connect(anim, "onEnd", function(e){
callback(node, anim);
});
};
anim.play(true);
return anim;
};
/////////////////////////////////////////////////////////////////////////////////////////
// TODO
/////////////////////////////////////////////////////////////////////////////////////////
// SLIDES
dojo.fx.svg.slideTo = function(node, endCoords, duration, callback) { };
dojo.fx.svg.slideBy = function(node, coords, duration, callback) { };
dojo.fx.svg.slide = function(node, startCoords, endCoords, duration, callback) {
var anim = new dojo.animation.Animation(
new dojo.math.curves.Line([startCoords],[endCoords]),
duration,
0
);
dojo.event.connect(anim, "onAnimate", function(e){
dojo.svg.setCoords(node, {x: e.x, y: e.y });
});
if (callback) {
dojo.event.connect(anim, "onEnd", function(e){
callback(node, anim);
});
};
anim.play(true);
return anim;
};
// COLORS
dojo.fx.svg.colorFadeIn = function(node, startRGB, duration, delay, callback) { };
dojo.fx.svg.highlight = dojo.fx.svg.colorFadeIn;
dojo.fx.svg.colorFadeFrom = dojo.fx.svg.colorFadeIn;
dojo.fx.svg.colorFadeOut = function(node, endRGB, duration, delay, callback) { };
dojo.fx.svg.unhighlight = dojo.fx.svg.colorFadeOut;
dojo.fx.svg.colorFadeTo = dojo.fx.svg.colorFadeOut;
dojo.fx.svg.colorFade = function(node, startRGB, endRGB, duration, callback, dontPlay) { };
// WIPES
dojo.fx.svg.wipeIn = function(node, duration, callback, dontPlay) { };
dojo.fx.svg.wipeInToHeight = function(node, duration, height, callback, dontPlay) { }
dojo.fx.svg.wipeOut = function(node, duration, callback, dontPlay) { };
// Explode and Implode
dojo.fx.svg.explode = function(startNode, endNode, duration, callback) { };
dojo.fx.svg.explodeFromBox = function(startCoords, endNode, duration, callback) { };
dojo.fx.svg.implode = function(startNode, endNode, duration, callback) { };
dojo.fx.svg.implodeToBox = function(startNode, endCoords, duration, callback) { };
dojo.fx.svg.Exploder = function(triggerNode, boxNode) { };
// html mixes in, we want SVG to remain separate

View file

@ -0,0 +1,944 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.graphics.Colorspace");
dojo.require("dojo.lang");
dojo.require("dojo.math.matrix");
//
// to convert to YUV:
// c.whitePoint = 'D65';
// c.RGBWorkingSpace = 'pal_secam_rgb';
// var out = c.convert([r,g,b], 'RGB', 'XYZ');
//
// to convert to YIQ:
// c.whitePoint = 'D65';
// c.RGBWorkingSpace = 'ntsc_rgb';
// var out = c.convert([r,g,b], 'RGB', 'XYZ');
//
dojo.graphics.Colorspace =function(){
this.whitePoint = 'D65';
this.stdObserver = '10';
this.chromaticAdaptationAlg = 'bradford';
this.RGBWorkingSpace = 's_rgb';
this.useApproxCIELabMapping = 1; // see http://www.brucelindbloom.com/LContinuity.html
this.chainMaps = {
'RGB_to_xyY' : ['XYZ'],
'xyY_to_RGB' : ['XYZ'],
'RGB_to_Lab' : ['XYZ'],
'Lab_to_RGB' : ['XYZ'],
'RGB_to_LCHab': ['XYZ', 'Lab'],
'LCHab_to_RGB': ['Lab'],
'xyY_to_Lab' : ['XYZ'],
'Lab_to_xyY' : ['XYZ'],
'XYZ_to_LCHab': ['Lab'],
'LCHab_to_XYZ': ['Lab'],
'xyY_to_LCHab': ['XYZ', 'Lab'],
'LCHab_to_xyY': ['Lab', 'XYZ'],
'RGB_to_Luv' : ['XYZ'],
'Luv_to_RGB' : ['XYZ'],
'xyY_to_Luv' : ['XYZ'],
'Luv_to_xyY' : ['XYZ'],
'Lab_to_Luv' : ['XYZ'],
'Luv_to_Lab' : ['XYZ'],
'LCHab_to_Luv': ['Lab', 'XYZ'],
'Luv_to_LCHab': ['XYZ', 'Lab'],
'RGB_to_LCHuv' : ['XYZ', 'Luv'],
'LCHuv_to_RGB' : ['Luv', 'XYZ'],
'XYZ_to_LCHuv' : ['Luv'],
'LCHuv_to_XYZ' : ['Luv'],
'xyY_to_LCHuv' : ['XYZ', 'Luv'],
'LCHuv_to_xyY' : ['Luv', 'XYZ'],
'Lab_to_LCHuv' : ['XYZ', 'Luv'],
'LCHuv_to_Lab' : ['Luv', 'XYZ'],
'LCHab_to_LCHuv': ['Lab', 'XYZ', 'Luv'],
'LCHuv_to_LCHab': ['Luv', 'XYZ', 'Lab'],
'XYZ_to_CMY' : ['RGB'],
'CMY_to_XYZ' : ['RGB'],
'xyY_to_CMY' : ['RGB'],
'CMY_to_xyY' : ['RGB'],
'Lab_to_CMY' : ['RGB'],
'CMY_to_Lab' : ['RGB'],
'LCHab_to_CMY' : ['RGB'],
'CMY_to_LCHab' : ['RGB'],
'Luv_to_CMY' : ['RGB'],
'CMY_to_Luv' : ['RGB'],
'LCHuv_to_CMY' : ['RGB'],
'CMY_to_LCHuv' : ['RGB'],
'XYZ_to_HSL' : ['RGB'],
'HSL_to_XYZ' : ['RGB'],
'xyY_to_HSL' : ['RGB'],
'HSL_to_xyY' : ['RGB'],
'Lab_to_HSL' : ['RGB'],
'HSL_to_Lab' : ['RGB'],
'LCHab_to_HSL' : ['RGB'],
'HSL_to_LCHab' : ['RGB'],
'Luv_to_HSL' : ['RGB'],
'HSL_to_Luv' : ['RGB'],
'LCHuv_to_HSL' : ['RGB'],
'HSL_to_LCHuv' : ['RGB'],
'CMY_to_HSL' : ['RGB'],
'HSL_to_CMY' : ['RGB'],
'CMYK_to_HSL' : ['RGB'],
'HSL_to_CMYK' : ['RGB'],
'XYZ_to_HSV' : ['RGB'],
'HSV_to_XYZ' : ['RGB'],
'xyY_to_HSV' : ['RGB'],
'HSV_to_xyY' : ['RGB'],
'Lab_to_HSV' : ['RGB'],
'HSV_to_Lab' : ['RGB'],
'LCHab_to_HSV' : ['RGB'],
'HSV_to_LCHab' : ['RGB'],
'Luv_to_HSV' : ['RGB'],
'HSV_to_Luv' : ['RGB'],
'LCHuv_to_HSV' : ['RGB'],
'HSV_to_LCHuv' : ['RGB'],
'CMY_to_HSV' : ['RGB'],
'HSV_to_CMY' : ['RGB'],
'CMYK_to_HSV' : ['RGB'],
'HSV_to_CMYK' : ['RGB'],
'HSL_to_HSV' : ['RGB'],
'HSV_to_HSL' : ['RGB'],
'XYZ_to_CMYK' : ['RGB'],
'CMYK_to_XYZ' : ['RGB'],
'xyY_to_CMYK' : ['RGB'],
'CMYK_to_xyY' : ['RGB'],
'Lab_to_CMYK' : ['RGB'],
'CMYK_to_Lab' : ['RGB'],
'LCHab_to_CMYK' : ['RGB'],
'CMYK_to_LCHab' : ['RGB'],
'Luv_to_CMYK' : ['RGB'],
'CMYK_to_Luv' : ['RGB'],
'LCHuv_to_CMYK' : ['RGB'],
'CMYK_to_LCHuv' : ['RGB']
};
return this;
}
dojo.graphics.Colorspace.prototype.convert = function(col, model_from, model_to){
var k = model_from+'_to_'+model_to;
if (this[k]){
return this[k](col);
}else{
if (this.chainMaps[k]){
var cur = model_from;
var models = this.chainMaps[k].concat();
models.push(model_to);
for(var i=0; i<models.length; i++){
col = this.convert(col, cur, models[i]);
cur = models[i];
}
return col;
}else{
dojo.debug("Can't convert from "+model_from+' to '+model_to);
}
}
}
dojo.graphics.Colorspace.prototype.munge = function(keys, args){
if (dojo.lang.isArray(args[0])){
args = args[0];
}
var out = new Array();
for (var i=0; i<keys.length; i++){
out[keys.charAt(i)] = args[i];
}
return out;
}
dojo.graphics.Colorspace.prototype.getWhitePoint = function(){
var x = 0;
var y = 0;
var t = 0;
// ref: http://en.wikipedia.org/wiki/White_point
// TODO: i need some good/better white point values
switch(this.stdObserver){
case '2' :
switch(this.whitePoint){
case 'E' : x=1/3 ; y=1/3 ; t=5400; break; //Equal energy
case 'D50' : x=0.34567; y=0.35850; t=5000; break;
case 'D55' : x=0.33242; y=0.34743; t=5500; break;
case 'D65' : x=0.31271; y=0.32902; t=6500; break;
case 'D75' : x=0.29902; y=0.31485; t=7500; break;
case 'A' : x=0.44757; y=0.40745; t=2856; break; //Incandescent tungsten
case 'B' : x=0.34842; y=0.35161; t=4874; break;
case 'C' : x=0.31006; y=0.31616; t=6774; break;
case '9300': x=0.28480; y=0.29320; t=9300; break; //Blue phosphor monitors
case 'F2' : x=0.37207; y=0.37512; t=4200; break; //Cool White Fluorescent
case 'F7' : x=0.31285; y=0.32918; t=6500; break; //Narrow Band Daylight Fluorescent
case 'F11' : x=0.38054; y=0.37691; t=4000; break; //Narrow Band White Fluorescent
default: dojo.debug('White point '+this.whitePoint+" isn't defined for Std. Observer "+this.strObserver);
};
break;
case '10' :
switch(this.whitePoint){
case 'E' : x=1/3 ; y=1/3 ; t=5400; break; //Equal energy
case 'D50' : x=0.34773; y=0.35952; t=5000; break;
case 'D55' : x=0.33411; y=0.34877; t=5500; break;
case 'D65' : x=0.31382; y=0.33100; t=6500; break;
case 'D75' : x=0.29968; y=0.31740; t=7500; break;
case 'A' : x=0.45117; y=0.40594; t=2856; break; //Incandescent tungsten
case 'B' : x=0.3498 ; y=0.3527 ; t=4874; break;
case 'C' : x=0.31039; y=0.31905; t=6774; break;
case 'F2' : x=0.37928; y=0.36723; t=4200; break; //Cool White Fluorescent
case 'F7' : x=0.31565; y=0.32951; t=6500; break; //Narrow Band Daylight Fluorescent
case 'F11' : x=0.38543; y=0.37110; t=4000; break; //Narrow Band White Fluorescent
default: dojo.debug('White point '+this.whitePoint+" isn't defined for Std. Observer "+this.strObserver);
};
break;
default:
dojo.debug("Std. Observer "+this.strObserver+" isn't defined");
}
var z = 1 - x - y;
var wp = {'x':x, 'y':y, 'z':z, 't':t};
wp.Y = 1;
var XYZ = this.xyY_to_XYZ([wp.x, wp.y, wp.Y]);
wp.X = XYZ[0];
wp.Y = XYZ[1];
wp.Z = XYZ[2];
return wp
}
dojo.graphics.Colorspace.prototype.getPrimaries = function(){
// ref: http://www.fho-emden.de/~hoffmann/ciexyz29082000.pdf
// ref: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
var m = [];
switch(this.RGBWorkingSpace){
case 'adobe_rgb_1998' : m = [2.2, 'D65', 0.6400, 0.3300, 0.297361, 0.2100, 0.7100, 0.627355, 0.1500, 0.0600, 0.075285]; break;
case 'apple_rgb' : m = [1.8, 'D65', 0.6250, 0.3400, 0.244634, 0.2800, 0.5950, 0.672034, 0.1550, 0.0700, 0.083332]; break;
case 'best_rgb' : m = [2.2, 'D50', 0.7347, 0.2653, 0.228457, 0.2150, 0.7750, 0.737352, 0.1300, 0.0350, 0.034191]; break;
case 'beta_rgb' : m = [2.2, 'D50', 0.6888, 0.3112, 0.303273, 0.1986, 0.7551, 0.663786, 0.1265, 0.0352, 0.032941]; break;
case 'bruce_rgb' : m = [2.2, 'D65', 0.6400, 0.3300, 0.240995, 0.2800, 0.6500, 0.683554, 0.1500, 0.0600, 0.075452]; break;
case 'cie_rgb' : m = [2.2, 'E' , 0.7350, 0.2650, 0.176204, 0.2740, 0.7170, 0.812985, 0.1670, 0.0090, 0.010811]; break;
case 'color_match_rgb' : m = [1.8, 'D50', 0.6300, 0.3400, 0.274884, 0.2950, 0.6050, 0.658132, 0.1500, 0.0750, 0.066985]; break;
case 'don_rgb_4' : m = [2.2, 'D50', 0.6960, 0.3000, 0.278350, 0.2150, 0.7650, 0.687970, 0.1300, 0.0350, 0.033680]; break;
case 'eci_rgb' : m = [1.8, 'D50', 0.6700, 0.3300, 0.320250, 0.2100, 0.7100, 0.602071, 0.1400, 0.0800, 0.077679]; break;
case 'ekta_space_ps5' : m = [2.2, 'D50', 0.6950, 0.3050, 0.260629, 0.2600, 0.7000, 0.734946, 0.1100, 0.0050, 0.004425]; break;
case 'ntsc_rgb' : m = [2.2, 'C' , 0.6700, 0.3300, 0.298839, 0.2100, 0.7100, 0.586811, 0.1400, 0.0800, 0.114350]; break;
case 'pal_secam_rgb' : m = [2.2, 'D65', 0.6400, 0.3300, 0.222021, 0.2900, 0.6000, 0.706645, 0.1500, 0.0600, 0.071334]; break;
case 'pro_photo_rgb' : m = [1.8, 'D50', 0.7347, 0.2653, 0.288040, 0.1596, 0.8404, 0.711874, 0.0366, 0.0001, 0.000086]; break;
case 'smpte-c_rgb' : m = [2.2, 'D65', 0.6300, 0.3400, 0.212395, 0.3100, 0.5950, 0.701049, 0.1550, 0.0700, 0.086556]; break;
case 's_rgb' : m = [2.2, 'D65', 0.6400, 0.3300, 0.212656, 0.3000, 0.6000, 0.715158, 0.1500, 0.0600, 0.072186]; break;
case 'wide_gamut_rgb' : m = [2.2, 'D50', 0.7350, 0.2650, 0.258187, 0.1150, 0.8260, 0.724938, 0.1570, 0.0180, 0.016875]; break;
default: dojo.debug("RGB working space "+this.RGBWorkingSpace+" isn't defined");
}
var p = {};
p.name = this.RGBWorkingSpace;
p.gamma = m[0];
p.wp = m[1];
p.xr = m[2];
p.yr = m[3];
p.Yr = m[4];
p.xg = m[5];
p.yg = m[6];
p.Yg = m[7];
p.xb = m[8];
p.yb = m[9];
p.Yb = m[10];
// if WP doesn't match current WP, convert the primaries over
if (p.wp != this.whitePoint){
var r = this.XYZ_to_xyY( this.chromaticAdaptation( this.xyY_to_XYZ([p.xr, p.yr, p.Yr]), p.wp, this.whitePoint ) );
var g = this.XYZ_to_xyY( this.chromaticAdaptation( this.xyY_to_XYZ([p.xg, p.yg, p.Yg]), p.wp, this.whitePoint ) );
var b = this.XYZ_to_xyY( this.chromaticAdaptation( this.xyY_to_XYZ([p.xb, p.yb, p.Yb]), p.wp, this.whitePoint ) );
p.xr = r[0];
p.yr = r[1];
p.Yr = r[2];
p.xg = g[0];
p.yg = g[1];
p.Yg = g[2];
p.xb = b[0];
p.yb = b[1];
p.Yb = b[2];
p.wp = this.whitePoint;
}
p.zr = 1 - p.xr - p.yr;
p.zg = 1 - p.xg - p.yg;
p.zb = 1 - p.xb - p.yb;
return p;
}
dojo.graphics.Colorspace.prototype.epsilon = function(){
return this.useApproxCIELabMapping ? 0.008856 : 216 / 24289;
}
dojo.graphics.Colorspace.prototype.kappa = function(){
return this.useApproxCIELabMapping ? 903.3 : 24389 / 27;
}
dojo.graphics.Colorspace.prototype.XYZ_to_xyY = function(){
var src = this.munge('XYZ', arguments);
var sum = src.X + src.Y + src.Z;
if (sum == 0){
var wp = this.getWhitePoint();
var x = wp.x;
var y = wp.y;
}else{
var x = src.X / sum;
var y = src.Y / sum;
}
var Y = src.Y;
return [x, y, Y];
}
dojo.graphics.Colorspace.prototype.xyY_to_XYZ = function(){
var src = this.munge('xyY', arguments);
if (src.y == 0){
var X = 0;
var Y = 0;
var Z = 0;
}else{
var X = (src.x * src.Y) / src.y;
var Y = src.Y;
var Z = ((1 - src.x - src.y) * src.Y) / src.y;
}
return [X, Y, Z];
}
dojo.graphics.Colorspace.prototype.RGB_to_XYZ = function(){
var src = this.munge('RGB', arguments);
var m = this.getRGB_XYZ_Matrix();
var pr = this.getPrimaries();
if (this.RGBWorkingSpace == 's_rgb'){
var r = (src.R > 0.04045) ? Math.pow(((src.R + 0.055) / 1.055), 2.4) : src.R / 12.92;
var g = (src.G > 0.04045) ? Math.pow(((src.G + 0.055) / 1.055), 2.4) : src.G / 12.92;
var b = (src.B > 0.04045) ? Math.pow(((src.B + 0.055) / 1.055), 2.4) : src.B / 12.92;
}else{
var r = Math.pow(src.R, pr.gamma);
var g = Math.pow(src.G, pr.gamma);
var b = Math.pow(src.B, pr.gamma);
}
var XYZ = dojo.math.matrix.multiply([[r, g, b]], m);
return [XYZ[0][0], XYZ[0][1], XYZ[0][2]];
}
dojo.graphics.Colorspace.prototype.XYZ_to_RGB = function(){
var src = this.munge('XYZ', arguments);
var mi = this.getXYZ_RGB_Matrix();
var pr = this.getPrimaries();
var rgb = dojo.math.matrix.multiply([[src.X, src.Y, src.Z]], mi);
var r = rgb[0][0];
var g = rgb[0][1];
var b = rgb[0][2];
if (this.RGBWorkingSpace == 's_rgb'){
var R = (r > 0.0031308) ? (1.055 * Math.pow(r, 1.0/2.4)) - 0.055 : 12.92 * r;
var G = (g > 0.0031308) ? (1.055 * Math.pow(g, 1.0/2.4)) - 0.055 : 12.92 * g;
var B = (b > 0.0031308) ? (1.055 * Math.pow(b, 1.0/2.4)) - 0.055 : 12.92 * b;
}else{
var R = Math.pow(r, 1/pr.gamma);
var G = Math.pow(g, 1/pr.gamma);
var B = Math.pow(b, 1/pr.gamma);
}
return [R, G, B];
}
dojo.graphics.Colorspace.prototype.XYZ_to_Lab = function(){
var src = this.munge('XYZ', arguments);
var wp = this.getWhitePoint();
var xr = src.X / wp.X;
var yr = src.Y / wp.Y;
var zr = src.Z / wp.Z;
var fx = (xr > this.epsilon()) ? Math.pow(xr, 1/3) : (this.kappa() * xr + 16) / 116;
var fy = (yr > this.epsilon()) ? Math.pow(yr, 1/3) : (this.kappa() * yr + 16) / 116;
var fz = (zr > this.epsilon()) ? Math.pow(zr, 1/3) : (this.kappa() * zr + 16) / 116;
var L = 116 * fy - 16;
var a = 500 * (fx - fy);
var b = 200 * (fy - fz);
return [L, a, b];
}
dojo.graphics.Colorspace.prototype.Lab_to_XYZ = function(){
var src = this.munge('Lab', arguments);
var wp = this.getWhitePoint();
var yr = (src.L > (this.kappa() * this.epsilon())) ? Math.pow((src.L + 16) / 116, 3) : src.L / this.kappa();
var fy = (yr > this.epsilon()) ? (src.L + 16) / 116 : (this.kappa() * yr + 16) / 116;
var fx = (src.a / 500) + fy;
var fz = fy - (src.b / 200);
var fxcube = Math.pow(fx, 3);
var fzcube = Math.pow(fz, 3);
var xr = (fxcube > this.epsilon()) ? fxcube : (116 * fx - 16) / this.kappa();
var zr = (fzcube > this.epsilon()) ? fzcube : (116 * fz - 16) / this.kappa();
var X = xr * wp.X;
var Y = yr * wp.Y;
var Z = zr * wp.Z;
return [X, Y, Z];
}
dojo.graphics.Colorspace.prototype.Lab_to_LCHab = function(){
var src = this.munge('Lab', arguments);
var L = src.L;
var C = Math.pow(src.a * src.a + src.b * src.b, 0.5);
var H = Math.atan2(src.b, src.a) * (180 / Math.PI);
if (H < 0){ H += 360; }
if (H > 360){ H -= 360; }
return [L, C, H];
}
dojo.graphics.Colorspace.prototype.LCHab_to_Lab = function(){
var src = this.munge('LCH', arguments);
var H_rad = src.H * (Math.PI / 180);
var L = src.L;
var a = src.C / Math.pow(Math.pow(Math.tan(H_rad), 2) + 1, 0.5);
if ((90 < src.H) && (src.H < 270)){ a= -a; }
var b = Math.pow(Math.pow(src.C, 2) - Math.pow(a, 2), 0.5);
if (src.H > 180){ b = -b; }
return [L, a, b];
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// this function converts an XYZ color array (col) from one whitepoint (src_w) to another (dst_w)
//
dojo.graphics.Colorspace.prototype.chromaticAdaptation = function(col, src_w, dst_w){
col = this.munge('XYZ', [col]);
//
// gather white point data for the source and dest
//
var old_wp = this.whitePoint;
this.whitePoint = src_w;
var wp_src = this.getWhitePoint();
this.whitePoint = dst_w;
var wp_dst = this.getWhitePoint();
this.whitePoint = old_wp;
//
// get a transformation matricies
//
switch(this.chromaticAdaptationAlg){
case 'xyz_scaling':
var ma = [[1,0,0],[0,1,0],[0,0,1]];
var mai = [[1,0,0],[0,1,0],[0,0,1]];
break;
case 'bradford':
var ma = [[0.8951, -0.7502, 0.0389],[0.2664, 1.7135, -0.0685],[-0.1614, 0.0367, 1.0296]];
var mai = [[0.986993, 0.432305, -0.008529],[-0.147054, 0.518360, 0.040043],[0.159963, 0.049291, 0.968487]];
break;
case 'von_kries':
var ma = [[0.40024, -0.22630, 0.00000],[0.70760, 1.16532, 0.00000],[-0.08081, 0.04570, 0.91822]]
var mai = [[1.859936, 0.361191, 0.000000],[-1.129382, 0.638812, 0.000000],[0.219897, -0.000006, 1.089064]]
break;
default:
dojo.debug("The "+this.chromaticAdaptationAlg+" chromatic adaptation algorithm matricies are not defined");
}
//
// calculate the cone response domains
//
var domain_src = dojo.math.matrix.multiply( [[wp_src.x, wp_src.y, wp_src.z]], ma);
var domain_dst = dojo.math.matrix.multiply( [[wp_dst.x, wp_dst.y, wp_dst.z]], ma);
//
// construct the centre matrix
//
var centre = [
[domain_dst[0][0]/domain_src[0][0], 0, 0],
[0, domain_dst[0][1]/domain_src[0][1], 0],
[0, 0, domain_dst[0][2]/domain_src[0][2]]
];
//
// caclulate 'm'
//
var m = dojo.math.matrix.multiply( dojo.math.matrix.multiply( ma, centre ), mai );
//
// construct source color matrix
//
var dst = dojo.math.matrix.multiply( [[ col.X, col.Y, col.Z ]], m );
return dst[0];
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
dojo.graphics.Colorspace.prototype.getRGB_XYZ_Matrix = function(){
var wp = this.getWhitePoint();
var pr = this.getPrimaries();
var Xr = pr.xr / pr.yr;
var Yr = 1;
var Zr = (1 - pr.xr - pr.yr) / pr.yr;
var Xg = pr.xg / pr.yg;
var Yg = 1;
var Zg = (1 - pr.xg - pr.yg) / pr.yg;
var Xb = pr.xb / pr.yb;
var Yb = 1;
var Zb = (1 - pr.xb - pr.yb) / pr.yb;
var m1 = [[Xr, Yr, Zr],[Xg, Yg, Zg],[Xb, Yb, Zb]];
var m2 = [[wp.X, wp.Y, wp.Z]];
var sm = dojo.math.matrix.multiply(m2, dojo.math.matrix.inverse(m1));
var Sr = sm[0][0];
var Sg = sm[0][1];
var Sb = sm[0][2];
var m4 = [[Sr*Xr, Sr*Yr, Sr*Zr],
[Sg*Xg, Sg*Yg, Sg*Zg],
[Sb*Xb, Sb*Yb, Sb*Zb]];
return m4;
}
dojo.graphics.Colorspace.prototype.getXYZ_RGB_Matrix = function(){
var m = this.getRGB_XYZ_Matrix();
return dojo.math.matrix.inverse(m);
}
dojo.graphics.Colorspace.prototype.XYZ_to_Luv = function(){
var src = this.munge('XYZ', arguments);
var wp = this.getWhitePoint();
var ud = (4 * src.X) / (src.X + 15 * src.Y + 3 * src.Z);
var vd = (9 * src.Y) / (src.X + 15 * src.Y + 3 * src.Z);
var udr = (4 * wp.X) / (wp.X + 15 * wp.Y + 3 * wp.Z);
var vdr = (9 * wp.Y) / (wp.X + 15 * wp.Y + 3 * wp.Z);
var yr = src.Y / wp.Y;
var L = (yr > this.epsilon()) ? 116 * Math.pow(yr, 1/3) - 16 : this.kappa() * yr;
var u = 13 * L * (ud-udr);
var v = 13 * L * (vd-vdr);
return [L, u, v];
}
dojo.graphics.Colorspace.prototype.Luv_to_XYZ = function(){
var src = this.munge('Luv', arguments);
var wp = this.getWhitePoint();
var uz = (4 * wp.X) / (wp.X + 15 * wp.Y + 3 * wp.Z);
var vz = (9 * wp.Y) / (wp.X + 15 * wp.Y + 3 * wp.Z);
var Y = (src.L > this.kappa() * this.epsilon()) ? Math.pow((src.L + 16) / 116, 3) : src.L / this.kappa();
var a = (1 / 3) * (((52 * src.L) / (src.u + 13 * src.L * uz)) - 1);
var b = -5 * Y;
var c = - (1 / 3);
var d = Y * (((39 * src.L) / (src.v + 13 * src.L * vz)) - 5);
var X = (d - b) / (a - c);
var Z = X * a + b;
return [X, Y, Z];
}
dojo.graphics.Colorspace.prototype.Luv_to_LCHuv = function(){
var src = this.munge('Luv', arguments);
var L = src.L;
var C = Math.pow(src.u * src.u + src.v * src.v, 0.5);
var H = Math.atan2(src.v, src.u) * (180 / Math.PI);
if (H < 0){ H += 360; }
if (H > 360){ H -= 360; }
return [L, C, H];
}
dojo.graphics.Colorspace.prototype.LCHuv_to_Luv = function(){
var src = this.munge('LCH', arguments);
var H_rad = src.H * (Math.PI / 180);
var L = src.L;
var u = src.C / Math.pow(Math.pow(Math.tan(H_rad), 2) + 1, 0.5);
var v = Math.pow(src.C * src.C - u * u, 0.5);
if ((90 < src.H) && (src.H < 270)){ u *= -1; }
if (src.H > 180){ v *= -1; }
return [L, u, v];
}
dojo.graphics.Colorspace.colorTemp_to_whitePoint = function(T){
if (T < 4000){
dojo.debug("Can't find a white point for temperatures under 4000K");
return [0,0];
}
if (T > 25000){
dojo.debug("Can't find a white point for temperatures over 25000K");
return [0,0];
}
var T1 = T;
var T2 = T * T;
var T3 = T2 * T;
var ten9 = Math.pow(10, 9);
var ten6 = Math.pow(10, 6);
var ten3 = Math.pow(10, 3);
if (T <= 7000){
var x = (-4.6070 * ten9 / T3) + (2.9678 * ten6 / T2) + (0.09911 * ten3 / T) + 0.244063;
}else{
var x = (-2.0064 * ten9 / T3) + (1.9018 * ten6 / T2) + (0.24748 * ten3 / T) + 0.237040;
}
var y = -3.000 * x * x + 2.870 * x - 0.275;
return [x, y];
}
dojo.graphics.Colorspace.prototype.RGB_to_CMY = function(){
var src = this.munge('RGB', arguments);
var C = 1 - src.R;
var M = 1 - src.G;
var Y = 1 - src.B;
return [C, M, Y];
}
dojo.graphics.Colorspace.prototype.CMY_to_RGB = function(){
var src = this.munge('CMY', arguments);
var R = 1 - src.C;
var G = 1 - src.M;
var B = 1 - src.Y;
return [R, G, B];
}
dojo.graphics.Colorspace.prototype.RGB_to_CMYK = function(){
var src = this.munge('RGB', arguments);
var K = Math.min(1-src.R, 1-src.G, 1-src.B);
var C = (1 - src.R - K) / (1 - K);
var M = (1 - src.G - K) / (1 - K);
var Y = (1 - src.B - K) / (1 - K);
return [C, M, Y, K];
}
dojo.graphics.Colorspace.prototype.CMYK_to_RGB = function(){
var src = this.munge('CMYK', arguments);
var R = 1 - Math.min(1, src.C * (1-src.K) + src.K);
var G = 1 - Math.min(1, src.M * (1-src.K) + src.K);
var B = 1 - Math.min(1, src.Y * (1-src.K) + src.K);
return [R, G, B];
}
dojo.graphics.Colorspace.prototype.CMY_to_CMYK = function(){
var src = this.munge('CMY', arguments);
var K = Math.min(src.C, src.M, src.Y);
var C = (src.C - K) / (1 - K);
var M = (src.M - K) / (1 - K);
var Y = (src.Y - K) / (1 - K);
return [C, M, Y, K];
}
dojo.graphics.Colorspace.prototype.CMYK_to_CMY = function(){
var src = this.munge('CMYK', arguments);
var C = Math.min(1, src.C * (1-src.K) + src.K);
var M = Math.min(1, src.M * (1-src.K) + src.K);
var Y = Math.min(1, src.Y * (1-src.K) + src.K);
return [C, M, Y];
}
dojo.graphics.Colorspace.prototype.RGB_to_HSV = function(){
var src = this.munge('RGB', arguments);
// Based on C Code in "Computer Graphics -- Principles and Practice,"
// Foley et al, 1996, p. 592.
var min = Math.min(src.R, src.G, src.B);
var V = Math.max(src.R, src.G, src.B);
var delta = V - min;
var H = null;
var S = (V == 0) ? 0 : delta / V;
if (S == 0){
H = 0;
}else{
if (src.R == V){
H = 60 * (src.G - src.B) / delta;
}else{
if (src.G == V){
H = 120 + 60 * (src.B - src.R) / delta;
}else{
if (src.B == V){
// between magenta and cyan
H = 240 + 60 * (src.R - src.G) / delta;
}
}
}
if (H < 0){
H += 360;
}
}
H = (H == 0) ? 360 : H;
return [H, S, V];
}
dojo.graphics.Colorspace.prototype.HSV_to_RGB = function(){
var src = this.munge('HSV', arguments);
if (src.H == 360){ src.H = 0;}
// Based on C Code in "Computer Graphics -- Principles and Practice,"
// Foley et al, 1996, p. 593.
var r = null;
var g = null;
var b = null;
if (src.S == 0){
// color is on black-and-white center line
// achromatic: shades of gray
var R = src.V;
var G = src.V;
var B = src.V;
}else{
// chromatic color
var hTemp = src.H / 60; // h is now IN [0,6]
var i = Math.floor(hTemp); // largest integer <= h
var f = hTemp - i; // fractional part of h
var p = src.V * (1 - src.S);
var q = src.V * (1 - (src.S * f));
var t = src.V * (1 - (src.S * (1 - f)));
switch(i){
case 0: R = src.V; G = t ; B = p ; break;
case 1: R = q ; G = src.V; B = p ; break;
case 2: R = p ; G = src.V; B = t ; break;
case 3: R = p ; G = q ; B = src.V; break;
case 4: R = t ; G = p ; B = src.V; break;
case 5: R = src.V; G = p ; B = q ; break;
}
}
return [R, G, B];
}
dojo.graphics.Colorspace.prototype.RGB_to_HSL = function(){
var src = this.munge('RGB', arguments);
//
// based on C code from http://astronomy.swin.edu.au/~pbourke/colour/hsl/
//
var min = Math.min(src.R, src.G, src.B);
var max = Math.max(src.R, src.G, src.B);
var delta = max - min;
var H = 0;
var S = 0;
var L = (min + max) / 2;
if ((L > 0) && (L < 1)){
S = delta / ((L < 0.5) ? (2 * L) : (2 - 2 * L));
}
if (delta > 0) {
if ((max == src.R) && (max != src.G)){
H += (src.G - src.B) / delta;
}
if ((max == src.G) && (max != src.B)){
H += (2 + (src.B - src.R) / delta);
}
if ((max == src.B) && (max != src.R)){
H += (4 + (src.R - src.G) / delta);
}
H *= 60;
}
H = (H == 0) ? 360 : H;
return [H, S, L];
}
dojo.graphics.Colorspace.prototype.HSL_to_RGB = function(){
var src = this.munge('HSL', arguments);
//
// based on C code from http://astronomy.swin.edu.au/~pbourke/colour/hsl/
//
while (src.H < 0){ src.H += 360; }
while (src.H >= 360){ src.H -= 360; }
var R = 0;
var G = 0;
var B = 0;
if (src.H < 120){
R = (120 - src.H) / 60;
G = src.H / 60;
B = 0;
}else if (src.H < 240){
R = 0;
G = (240 - src.H) / 60;
B = (src.H - 120) / 60;
}else{
R = (src.H - 240) / 60;
G = 0;
B = (360 - src.H) / 60;
}
R = 2 * src.S * Math.min(R, 1) + (1 - src.S);
G = 2 * src.S * Math.min(G, 1) + (1 - src.S);
B = 2 * src.S * Math.min(B, 1) + (1 - src.S);
if (src.L < 0.5){
R = src.L * R;
G = src.L * G;
B = src.L * B;
}else{
R = (1 - src.L) * R + 2 * src.L - 1;
G = (1 - src.L) * G + 2 * src.L - 1;
B = (1 - src.L) * B + 2 * src.L - 1;
}
return [R, G, B];
}

View file

@ -0,0 +1,15 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
browser: ["dojo.graphics.htmlEffects"],
dashboard: ["dojo.graphics.htmlEffects"]
});
dojo.provide("dojo.graphics.*");

View file

@ -0,0 +1,166 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.graphics.color");
dojo.require("dojo.lang.array");
// TODO: rewrite the "x2y" methods to take advantage of the parsing
// abilities of the Color object. Also, beef up the Color
// object (as possible) to parse most common formats
// takes an r, g, b, a(lpha) value, [r, g, b, a] array, "rgb(...)" string, hex string (#aaa, #aaaaaa, aaaaaaa)
dojo.graphics.color.Color = function(r, g, b, a) {
// dojo.debug("r:", r[0], "g:", r[1], "b:", r[2]);
if(dojo.lang.isArray(r)) {
this.r = r[0];
this.g = r[1];
this.b = r[2];
this.a = r[3]||1.0;
} else if(dojo.lang.isString(r)) {
var rgb = dojo.graphics.color.extractRGB(r);
this.r = rgb[0];
this.g = rgb[1];
this.b = rgb[2];
this.a = g||1.0;
} else if(r instanceof dojo.graphics.color.Color) {
this.r = r.r;
this.b = r.b;
this.g = r.g;
this.a = r.a;
} else {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
}
dojo.graphics.color.Color.fromArray = function(arr) {
return new dojo.graphics.color.Color(arr[0], arr[1], arr[2], arr[3]);
}
dojo.lang.extend(dojo.graphics.color.Color, {
toRgb: function(includeAlpha) {
if(includeAlpha) {
return this.toRgba();
} else {
return [this.r, this.g, this.b];
}
},
toRgba: function() {
return [this.r, this.g, this.b, this.a];
},
toHex: function() {
return dojo.graphics.color.rgb2hex(this.toRgb());
},
toCss: function() {
return "rgb(" + this.toRgb().join() + ")";
},
toString: function() {
return this.toHex(); // decent default?
},
blend: function(color, weight) {
return dojo.graphics.color.blend(this.toRgb(), new dojo.graphics.color.Color(color).toRgb(), weight);
}
});
dojo.graphics.color.named = {
white: [255,255,255],
black: [0,0,0],
red: [255,0,0],
green: [0,255,0],
blue: [0,0,255],
navy: [0,0,128],
gray: [128,128,128],
silver: [192,192,192]
};
// blend colors a and b (both as RGB array or hex strings) with weight from -1 to +1, 0 being a 50/50 blend
dojo.graphics.color.blend = function(a, b, weight) {
if(typeof a == "string") { return dojo.graphics.color.blendHex(a, b, weight); }
if(!weight) { weight = 0; }
else if(weight > 1) { weight = 1; }
else if(weight < -1) { weight = -1; }
var c = new Array(3);
for(var i = 0; i < 3; i++) {
var half = Math.abs(a[i] - b[i])/2;
c[i] = Math.floor(Math.min(a[i], b[i]) + half + (half * weight));
}
return c;
}
// very convenient blend that takes and returns hex values
// (will get called automatically by blend when blend gets strings)
dojo.graphics.color.blendHex = function(a, b, weight) {
return dojo.graphics.color.rgb2hex(dojo.graphics.color.blend(dojo.graphics.color.hex2rgb(a), dojo.graphics.color.hex2rgb(b), weight));
}
// get RGB array from css-style color declarations
dojo.graphics.color.extractRGB = function(color) {
var hex = "0123456789abcdef";
color = color.toLowerCase();
if( color.indexOf("rgb") == 0 ) {
var matches = color.match(/rgba*\((\d+), *(\d+), *(\d+)/i);
var ret = matches.splice(1, 3);
return ret;
} else {
var colors = dojo.graphics.color.hex2rgb(color);
if(colors) {
return colors;
} else {
// named color (how many do we support?)
return dojo.graphics.color.named[color] || [255, 255, 255];
}
}
}
dojo.graphics.color.hex2rgb = function(hex) {
var hexNum = "0123456789ABCDEF";
var rgb = new Array(3);
if( hex.indexOf("#") == 0 ) { hex = hex.substring(1); }
hex = hex.toUpperCase();
if(hex.replace(new RegExp("["+hexNum+"]", "g"), "") != "") {
return null;
}
if( hex.length == 3 ) {
rgb[0] = hex.charAt(0) + hex.charAt(0)
rgb[1] = hex.charAt(1) + hex.charAt(1)
rgb[2] = hex.charAt(2) + hex.charAt(2);
} else {
rgb[0] = hex.substring(0, 2);
rgb[1] = hex.substring(2, 4);
rgb[2] = hex.substring(4);
}
for(var i = 0; i < rgb.length; i++) {
rgb[i] = hexNum.indexOf(rgb[i].charAt(0)) * 16 + hexNum.indexOf(rgb[i].charAt(1));
}
return rgb;
}
dojo.graphics.color.rgb2hex = function(r, g, b) {
if(dojo.lang.isArray(r)) {
g = r[1] || 0;
b = r[2] || 0;
r = r[0] || 0;
}
var ret = dojo.lang.map([r, g, b], function(x) {
x = new Number(x);
var s = x.toString(16);
while(s.length < 2) { s = "0" + s; }
return s;
});
ret.unshift("#");
return ret.join("");
}

View file

@ -0,0 +1,144 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.graphics.color.hsl");
dojo.require("dojo.lang.array");
dojo.lang.extend(dojo.graphics.color.Color, {
toHsl: function() {
return dojo.graphics.color.rgb2hsl(this.toRgb());
}
});
dojo.graphics.color.rgb2hsl = function(r, g, b){
if (dojo.lang.isArray(r)) {
b = r[2] || 0;
g = r[1] || 0;
r = r[0] || 0;
}
r /= 255;
g /= 255;
b /= 255;
//
// based on C code from http://astronomy.swin.edu.au/~pbourke/colour/hsl/
//
var h = null;
var s = null;
var l = null;
var min = Math.min(r, g, b);
var max = Math.max(r, g, b);
var delta = max - min;
l = (min + max) / 2;
s = 0;
if ((l > 0) && (l < 1)){
s = delta / ((l < 0.5) ? (2 * l) : (2 - 2 * l));
}
h = 0;
if (delta > 0) {
if ((max == r) && (max != g)){
h += (g - b) / delta;
}
if ((max == g) && (max != b)){
h += (2 + (b - r) / delta);
}
if ((max == b) && (max != r)){
h += (4 + (r - g) / delta);
}
h *= 60;
}
h = (h == 0) ? 360 : Math.ceil((h / 360) * 255);
s = Math.ceil(s * 255);
l = Math.ceil(l * 255);
return [h, s, l];
}
dojo.graphics.color.hsl2rgb = function(h, s, l){
if (dojo.lang.isArray(h)) {
l = h[2] || 0;
s = h[1] || 0;
h = h[0] || 0;
}
h = (h / 255) * 360;
if (h == 360){ h = 0;}
s = s / 255;
l = l / 255;
//
// based on C code from http://astronomy.swin.edu.au/~pbourke/colour/hsl/
//
while (h < 0){ h += 360; }
while (h > 360){ h -= 360; }
var r, g, b;
if (h < 120){
r = (120 - h) / 60;
g = h / 60;
b = 0;
}else if (h < 240){
r = 0;
g = (240 - h) / 60;
b = (h - 120) / 60;
}else{
r = (h - 240) / 60;
g = 0;
b = (360 - h) / 60;
}
r = Math.min(r, 1);
g = Math.min(g, 1);
b = Math.min(b, 1);
r = 2 * s * r + (1 - s);
g = 2 * s * g + (1 - s);
b = 2 * s * b + (1 - s);
if (l < 0.5){
r = l * r;
g = l * g;
b = l * b;
}else{
r = (1 - l) * r + 2 * l - 1;
g = (1 - l) * g + 2 * l - 1;
b = (1 - l) * b + 2 * l - 1;
}
r = Math.ceil(r * 255);
g = Math.ceil(g * 255);
b = Math.ceil(b * 255);
return [r, g, b];
}
dojo.graphics.color.hsl2hex = function(h, s, l){
var rgb = dojo.graphics.color.hsl2rgb(h, s, l);
return dojo.graphics.color.rgb2hex(rgb[0], rgb[1], rgb[2]);
}
dojo.graphics.color.hex2hsl = function(hex){
var rgb = dojo.graphics.color.hex2rgb(hex);
return dojo.graphics.color.rgb2hsl(rgb[0], rgb[1], rgb[2]);
}

View file

@ -0,0 +1,141 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.graphics.color.hsv");
dojo.require("dojo.lang.array");
dojo.lang.extend(dojo.graphics.color.Color, {
toHsv: function() {
return dojo.graphics.color.rgb2hsv(this.toRgb());
}
});
dojo.graphics.color.rgb2hsv = function(r, g, b){
if (dojo.lang.isArray(r)) {
b = r[2] || 0;
g = r[1] || 0;
r = r[0] || 0;
}
// r,g,b, each 0 to 255, to HSV.
// h = 0.0 to 360.0 (corresponding to 0..360.0 degrees around hexcone)
// s = 0.0 (shade of gray) to 1.0 (pure color)
// v = 0.0 (black) to 1.0 {white)
//
// Based on C Code in "Computer Graphics -- Principles and Practice,"
// Foley et al, 1996, p. 592.
//
// our calculatuions are based on 'regular' values (0-360, 0-1, 0-1)
// but we return bytes values (0-255, 0-255, 0-255)
var h = null;
var s = null;
var v = null;
var min = Math.min(r, g, b);
v = Math.max(r, g, b);
var delta = v - min;
// calculate saturation (0 if r, g and b are all 0)
s = (v == 0) ? 0 : delta/v;
if (s == 0){
// achromatic: when saturation is, hue is undefined
h = 0;
}else{
// chromatic
if (r == v){
// between yellow and magenta
h = 60 * (g - b) / delta;
}else{
if (g == v){
// between cyan and yellow
h = 120 + 60 * (b - r) / delta;
}else{
if (b == v){
// between magenta and cyan
h = 240 + 60 * (r - g) / delta;
}
}
}
if (h < 0){
h += 360;
}
}
h = (h == 0) ? 360 : Math.ceil((h / 360) * 255);
s = Math.ceil(s * 255);
return [h, s, v];
}
dojo.graphics.color.hsv2rgb = function(h, s, v){
if (dojo.lang.isArray(h)) {
v = h[2] || 0;
s = h[1] || 0;
h = h[0] || 0;
}
h = (h / 255) * 360;
if (h == 360){ h = 0;}
s = s / 255;
v = v / 255;
// Based on C Code in "Computer Graphics -- Principles and Practice,"
// Foley et al, 1996, p. 593.
//
// H = 0.0 to 360.0 (corresponding to 0..360 degrees around hexcone) 0 for S = 0
// S = 0.0 (shade of gray) to 1.0 (pure color)
// V = 0.0 (black) to 1.0 (white)
var r = null;
var g = null;
var b = null;
if (s == 0){
// color is on black-and-white center line
// achromatic: shades of gray
r = v;
g = v;
b = v;
}else{
// chromatic color
var hTemp = h / 60; // h is now IN [0,6]
var i = Math.floor(hTemp); // largest integer <= h
var f = hTemp - i; // fractional part of h
var p = v * (1 - s);
var q = v * (1 - (s * f));
var t = v * (1 - (s * (1 - f)));
switch(i){
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
}
}
r = Math.ceil(r * 255);
g = Math.ceil(g * 255);
b = Math.ceil(b * 255);
return [r, g, b];
}

View file

@ -0,0 +1,571 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/*
* Adobe SVG Viewer host environment
*/
if(typeof window == 'undefined'){
dojo.raise("attempt to use adobe svg hostenv when no window object");
}
with(dojo.render){
name = navigator.appName;
ver = parseFloat(navigator.appVersion, 10);
switch(navigator.platform){
case "MacOS":
os.osx = true;
break;
case "Linux":
os.linux = true;
break;
case "Windows":
os.win = true;
break;
default:
os.linux = true;
break;
};
svg.capable = true;
svg.support.builtin = true;
svg.adobe = true;
};
// browserEval("alert(window.location);");
dojo.hostenv.println = function(s){
try{
// FIXME: this may not work with adobe's viewer, as we may first need a
// reference to the svgDocument
// FIXME: need a way to determine where to position the text for this
var ti = document.createElement("text");
ti.setAttribute("x","50");
var yPos = 25 + 15*document.getElementsByTagName("text").length;
ti.setAttribute("y",yPos);
var tn = document.createTextNode(s);
ti.appendChild(tn);
document.documentElement.appendChild(ti);
}catch(e){
}
}
dojo.debug = function() {
if (!djConfig.isDebug) { return; }
var args = arguments;
if(typeof dojo.hostenv.println != 'function'){
dojo.raise("attempt to call dojo.debug when there is no dojo.hostenv println implementation (yet?)");
}
var isJUM = dj_global["jum"];
var s = isJUM ? "": "DEBUG: ";
for(var i=0;i<args.length;++i){ s += args[i]; }
if(isJUM){ // this seems to be the only way to get JUM to "play nice"
jum.debug(s);
}else{
dojo.hostenv.println(s);
}
}
dojo.hostenv.startPackage("dojo.hostenv");
dojo.hostenv.name_ = 'adobesvg';
dojo.hostenv.anonCtr = 0;
dojo.hostenv.anon = {};
dojo.hostenv.nameAnonFunc = function(anonFuncPtr, namespaceObj){
var ret = "_"+this.anonCtr++;
var nso = (namespaceObj || this.anon);
while(typeof nso[ret] != "undefined"){
ret = "_"+this.anonCtr++;
}
nso[ret] = anonFuncPtr;
return ret;
}
dojo.hostenv.modulesLoadedFired = false;
dojo.hostenv.modulesLoadedListeners = [];
dojo.hostenv.getTextStack = [];
dojo.hostenv.loadUriStack = [];
dojo.hostenv.loadedUris = [];
dojo.hostenv.modulesLoaded = function(){
if(this.modulesLoadedFired){ return; }
if((this.loadUriStack.length==0)&&(this.getTextStack.length==0)){
if(this.inFlightCount > 0){
dojo.debug("couldn't initialize, there are files still in flight");
return;
}
this.modulesLoadedFired = true;
var mll = this.modulesLoadedListeners;
for(var x=0; x<mll.length; x++){
mll[x]();
}
}
}
dojo.hostenv.getNewAnonFunc = function(){
var ret = "_"+this.anonCtr++;
while(typeof this.anon[ret] != "undefined"){
ret = "_"+this.anonCtr++;
}
// this.anon[ret] = function(){};
eval("dojo.nostenv.anon."+ret+" = function(){};");
return [ret, this.anon[ret]];
}
dojo.hostenv.displayStack = function(){
var oa = [];
var stack = this.loadUriStack;
for(var x=0; x<stack.length; x++){
oa.unshift([stack[x][0], (typeof stack[x][2])]);
}
dojo.debug("<pre>"+oa.join("\n")+"</pre>");
}
dojo.hostenv.unwindUriStack = function(){
var stack = this.loadUriStack;
for(var x in dojo.hostenv.loadedUris){
for(var y=stack.length-1; y>=0; y--){
if(stack[y][0]==x){
stack.splice(y, 1);
}
}
}
var next = stack.pop();
if((!next)&&(stack.length==0)){
return;
}
for(var x=0; x<stack.length; x++){
if((stack[x][0]==next[0])&&(stack[x][2])){
next[2] == stack[x][2]
}
}
var last = next;
while(dojo.hostenv.loadedUris[next[0]]){
last = next;
next = stack.pop();
}
while(typeof next[2] == "string"){ // unwind as far as we can
try{
// dojo.debug("<pre><![CDATA["+next[2]+"]]></pre>");
dj_eval(next[2]);
next[1](true);
}catch(e){
dojo.debug("we got an error when loading "+next[0]);
dojo.debug("error: "+e);
// for(var x in e){ alert(x+" "+e[x]); }
}
dojo.hostenv.loadedUris[next[0]] = true;
dojo.hostenv.loadedUris.push(next[0]);
last = next;
next = stack.pop();
if((!next)&&(stack.length==0)){ break; }
while(dojo.hostenv.loadedUris[next[0]]){
last = next;
next = stack.pop();
}
}
if(next){
stack.push(next);
dojo.debug("### CHOKED ON: "+next[0]);
}
}
/**
* Reads the contents of the URI, and evaluates the contents.
* Returns true if it succeeded. Returns false if the URI reading failed. Throws if the evaluation throws.
* The result of the eval is not available to the caller.
*/
dojo.hostenv.loadUri = function(uri, cb){
if(dojo.hostenv.loadedUris[uri]){
return;
}
var stack = this.loadUriStack;
stack.push([uri, cb, null]);
var tcb = function(contents){
// gratuitous hack for Adobe SVG 3, what a fucking POS
if(contents.content){
contents = contents.content;
}
// stack management
var next = stack.pop();
if((!next)&&(stack.length==0)){
dojo.hostenv.modulesLoaded();
return;
}
if(typeof contents == "string"){
stack.push(next);
for(var x=0; x<stack.length; x++){
if(stack[x][0]==uri){
stack[x][2] = contents;
}
}
next = stack.pop();
}
if(dojo.hostenv.loadedUris[next[0]]){
// dojo.debug("WE ALREADY HAD: "+next[0]);
dojo.hostenv.unwindUriStack();
return;
}
// push back onto stack
stack.push(next);
if(next[0]!=uri){
// and then unwind as far as we can
if(typeof next[2] == "string"){
dojo.hostenv.unwindUriStack();
}
}else{
if(!contents){
next[1](false);
}else{
var deps = dojo.hostenv.getDepsForEval(next[2]);
if(deps.length>0){
eval(deps.join(";"));
}else{
dojo.hostenv.unwindUriStack();
}
}
}
}
this.getText(uri, tcb, true);
}
/**
* Reads the contents of the URI, and evaluates the contents.
* Returns true if it succeeded. Returns false if the URI reading failed. Throws if the evaluation throws.
* The result of the eval is not available to the caller.
*/
dojo.hostenv.loadUri = function(uri, cb){
if(dojo.hostenv.loadedUris[uri]){
return;
}
var stack = this.loadUriStack;
stack.push([uri, cb, null]);
var tcb = function(contents){
// gratuitous hack for Adobe SVG 3, what a fucking POS
if(contents.content){
contents = contents.content;
}
// stack management
var next = stack.pop();
if((!next)&&(stack.length==0)){
dojo.hostenv.modulesLoaded();
return;
}
if(typeof contents == "string"){
stack.push(next);
for(var x=0; x<stack.length; x++){
if(stack[x][0]==uri){
stack[x][2] = contents;
}
}
next = stack.pop();
}
if(dojo.hostenv.loadedUris[next[0]]){
// dojo.debug("WE ALREADY HAD: "+next[0]);
dojo.hostenv.unwindUriStack();
return;
}
// push back onto stack
stack.push(next);
if(next[0]!=uri){
// and then unwind as far as we can
if(typeof next[2] == "string"){
dojo.hostenv.unwindUriStack();
}
}else{
if(!contents){
next[1](false);
}else{
var deps = dojo.hostenv.getDepsForEval(next[2]);
if(deps.length>0){
eval(deps.join(";"));
}else{
dojo.hostenv.unwindUriStack();
}
}
}
}
this.getText(uri, tcb, true);
}
/**
* loadModule("A.B") first checks to see if symbol A.B is defined.
* If it is, it is simply returned (nothing to do).
* If it is not defined, it will look for "A/B.js" in the script root directory, followed
* by "A.js".
* It throws if it cannot find a file to load, or if the symbol A.B is not defined after loading.
* It returns the object A.B.
*
* This does nothing about importing symbols into the current package.
* It is presumed that the caller will take care of that. For example, to import
* all symbols:
*
* with (dojo.hostenv.loadModule("A.B")) {
* ...
* }
*
* And to import just the leaf symbol:
*
* var B = dojo.hostenv.loadModule("A.B");
* ...
*
* dj_load is an alias for dojo.hostenv.loadModule
*/
dojo.hostenv.loadModule = function(modulename, exact_only, omit_module_check){
// alert("dojo.hostenv.loadModule('"+modulename+"');");
var module = this.findModule(modulename, 0);
if(module){
return module;
}
// dojo.debug("dojo.hostenv.loadModule('"+modulename+"');");
// protect against infinite recursion from mutual dependencies
if (typeof this.loading_modules_[modulename] !== 'undefined'){
// NOTE: this should never throw an exception!! "recursive" includes
// are normal in the course of app and module building, so blow out of
// it gracefully, but log it in debug mode
// dojo.raise("recursive attempt to load module '" + modulename + "'");
dojo.debug("recursive attempt to load module '" + modulename + "'");
}else{
this.addedToLoadingCount.push(modulename);
}
this.loading_modules_[modulename] = 1;
// convert periods to slashes
var relpath = modulename.replace(/\./g, '/') + '.js';
var syms = modulename.split(".");
var nsyms = modulename.split(".");
if(syms[0]=="dojo"){ // FIXME: need a smarter way to do this!
syms[0] = "src";
}
var last = syms.pop();
syms.push(last);
// figure out if we're looking for a full package, if so, we want to do
// things slightly diffrently
var _this = this;
var pfn = this.pkgFileName;
if(last=="*"){
modulename = (nsyms.slice(0, -1)).join('.');
var module = this.findModule(modulename, 0);
// dojo.debug("found: "+modulename+"="+module);
if(module){
_this.removedFromLoadingCount.push(modulename);
return module;
}
var nextTry = function(lastStatus){
if(lastStatus){
module = _this.findModule(modulename, false); // pass in false so we can give better error
if((!module)&&(syms[syms.length-1]!=pfn)){
dojo.raise("Module symbol '" + modulename + "' is not defined after loading '" + relpath + "'");
}
if(module){
_this.removedFromLoadingCount.push(modulename);
dojo.hostenv.modulesLoaded();
return;
}
}
syms.pop();
syms.push(pfn);
// dojo.debug("syms: "+syms);
relpath = syms.join("/") + '.js';
if(relpath.charAt(0)=="/"){
relpath = relpath.slice(1);
}
// dojo.debug("relpath: "+relpath);
_this.loadPath(relpath, ((!omit_module_check) ? modulename : null), nextTry);
}
nextTry();
}else{
relpath = syms.join("/") + '.js';
modulename = nsyms.join('.');
var nextTry = function(lastStatus){
// dojo.debug("lastStatus: "+lastStatus);
if(lastStatus){
// dojo.debug("inital relpath: "+relpath);
module = _this.findModule(modulename, false); // pass in false so we can give better error
// if(!module){
if((!module)&&(syms[syms.length-1]!=pfn)){
dojo.raise("Module symbol '" + modulename + "' is not defined after loading '" + relpath + "'");
}
if(module){
_this.removedFromLoadingCount.push(modulename);
dojo.hostenv.modulesLoaded();
return;
}
}
var setPKG = (syms[syms.length-1]==pfn) ? false : true;
syms.pop();
if(setPKG){
syms.push(pfn);
}
relpath = syms.join("/") + '.js';
if(relpath.charAt(0)=="/"){
relpath = relpath.slice(1);
}
// dojo.debug("relpath: "+relpath);
_this.loadPath(relpath, ((!omit_module_check) ? modulename : null), nextTry);
}
this.loadPath(relpath, ((!omit_module_check) ? modulename : null), nextTry);
}
return;
}
/**
* Read the contents of the specified uri and return those contents.
*
* FIXME: Make sure this is consistent with other implementations of getText
* @param uri A relative or absolute uri. If absolute, it still must be in the same "domain" as we are.
* @param async_cb If not specified, returns false as synchronous is not
* supported. If specified, load asynchronously, and use async_cb as the handler which receives the result of the request.
* @param fail_ok Default false. If fail_ok and !async_cb and loading fails, return null instead of throwing.
*/
dojo.hostenv.async_cb = null;
dojo.hostenv.unWindGetTextStack = function(){
if(dojo.hostenv.inFlightCount>0){
setTimeout("dojo.hostenv.unWindGetTextStack()", 100);
return;
}
// we serialize because this goddamned environment is too fucked up
// to know how to do anything else
dojo.hostenv.inFlightCount++;
var next = dojo.hostenv.getTextStack.pop();
if((!next)&&(dojo.hostenv.getTextStack.length==0)){
dojo.hostenv.inFlightCount--;
dojo.hostenv.async_cb = function(){};
return;
}
dojo.hostenv.async_cb = next[1];
// http = window.getURL(uri, dojo.hostenv.anon[cbn]);
window.getURL(next[0], function(result){
dojo.hostenv.inFlightCount--;
dojo.hostenv.async_cb(result.content);
dojo.hostenv.unWindGetTextStack();
});
}
dojo.hostenv.getText = function(uri, async_cb, fail_ok){
// dojo.debug("Calling getText()");
try{
if(async_cb){
dojo.hostenv.getTextStack.push([uri, async_cb, fail_ok]);
dojo.hostenv.unWindGetTextStack();
}else{
return dojo.raise("No synchronous XMLHTTP implementation available, for uri " + uri);
}
}catch(e){
return dojo.raise("No XMLHTTP implementation available, for uri " + uri);
}
}
/**
* Makes an async post to the specified uri.
*
* FIXME: Not sure that we need this, but adding for completeness.
* More details about the implementation of this are available at
* http://wiki.svg.org/index.php/PostUrl
* @param uri A relative or absolute uri. If absolute, it still must be in the same "domain" as we are.
* @param async_cb If not specified, returns false as synchronous is not
* supported. If specified, load asynchronously, and use async_cb as the progress handler which takes the xmlhttp object as its argument. If async_cb, this function returns null.
* @param text Data to post
* @param fail_ok Default false. If fail_ok and !async_cb and loading fails, return null instead of throwing.
* @param mime_type optional MIME type of the posted data (such as "text/plain")
* @param encoding optional encoding for data. null, 'gzip' and 'deflate' are possible values. If browser does not support binary post this parameter is ignored.
*/
dojo.hostenv.postText = function(uri, async_cb, text, fail_ok, mime_type, encoding){
var http = null;
var async_callback = function(httpResponse){
if (!httpResponse.success) {
dojo.raise("Request for uri '" + uri + "' resulted in " + httpResponse.status);
}
if(!httpResponse.content) {
if (!fail_ok) dojo.raise("Request for uri '" + uri + "' resulted in no content");
return null;
}
// FIXME: wtf, I'm losing a reference to async_cb
async_cb(httpResponse.content);
}
try {
if(async_cb) {
http = window.postURL(uri, text, async_callback, mimeType, encoding);
} else {
return dojo.raise("No synchronous XMLHTTP post implementation available, for uri " + uri);
}
} catch(e) {
return dojo.raise("No XMLHTTP post implementation available, for uri " + uri);
}
}
/*
* It turns out that if we check *right now*, as this script file is being loaded,
* then the last script element in the window DOM is ourselves.
* That is because any subsequent script elements haven't shown up in the document
* object yet.
*/
function dj_last_script_src() {
var scripts = window.document.getElementsByTagName('script');
if(scripts.length < 1){
dojo.raise("No script elements in window.document, so can't figure out my script src");
}
var li = scripts.length-1;
var xlinkNS = "http://www.w3.org/1999/xlink";
var src = null;
var script = null;
while(!src){
script = scripts.item(li);
src = script.getAttributeNS(xlinkNS,"href");
li--;
if(li<0){ break; }
// break;
}
if(!src){
dojo.raise("Last script element (out of " + scripts.length + ") has no src");
}
return src;
}
if(!dojo.hostenv["library_script_uri_"]){
dojo.hostenv.library_script_uri_ = dj_last_script_src();
}
// dojo.hostenv.loadUri = function(uri){
/* FIXME: adding a script element doesn't seem to be synchronous, and so
* checking for namespace or object existance after loadUri using this
* method will error out. Need to figure out some other way of handling
* this!
*/
/*
var se = document.createElement("script");
se.src = uri;
var head = document.getElementsByTagName("head")[0];
head.appendChild(se);
// document.write("<script type='text/javascript' src='"+uri+"' />");
return 1;
}
*/

View file

@ -0,0 +1,360 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
if(typeof window == 'undefined'){
dojo.raise("no window object");
}
// attempt to figure out the path to dojo if it isn't set in the config
(function() {
// before we get any further with the config options, try to pick them out
// of the URL. Most of this code is from NW
if(djConfig.allowQueryConfig){
var baseUrl = document.location.toString(); // FIXME: use location.query instead?
var params = baseUrl.split("?", 2);
if(params.length > 1){
var paramStr = params[1];
var pairs = paramStr.split("&");
for(var x in pairs){
var sp = pairs[x].split("=");
// FIXME: is this eval dangerous?
if((sp[0].length > 9)&&(sp[0].substr(0, 9) == "djConfig.")){
var opt = sp[0].substr(9);
try{
djConfig[opt]=eval(sp[1]);
}catch(e){
djConfig[opt]=sp[1];
}
}
}
}
}
if(((djConfig["baseScriptUri"] == "")||(djConfig["baseRelativePath"] == "")) &&(document && document.getElementsByTagName)){
var scripts = document.getElementsByTagName("script");
var rePkg = /(__package__|dojo|bootstrap1)\.js([\?\.]|$)/i;
for(var i = 0; i < scripts.length; i++) {
var src = scripts[i].getAttribute("src");
if(!src) { continue; }
var m = src.match(rePkg);
if(m) {
var root = src.substring(0, m.index);
if(src.indexOf("bootstrap1") > -1) { root += "../"; }
if(!this["djConfig"]) { djConfig = {}; }
if(djConfig["baseScriptUri"] == "") { djConfig["baseScriptUri"] = root; }
if(djConfig["baseRelativePath"] == "") { djConfig["baseRelativePath"] = root; }
break;
}
}
}
// fill in the rendering support information in dojo.render.*
var dr = dojo.render;
var drh = dojo.render.html;
var drs = dojo.render.svg;
var dua = drh.UA = navigator.userAgent;
var dav = drh.AV = navigator.appVersion;
var t = true;
var f = false;
drh.capable = t;
drh.support.builtin = t;
dr.ver = parseFloat(drh.AV);
dr.os.mac = dav.indexOf("Macintosh") >= 0;
dr.os.win = dav.indexOf("Windows") >= 0;
// could also be Solaris or something, but it's the same browser
dr.os.linux = dav.indexOf("X11") >= 0;
drh.opera = dua.indexOf("Opera") >= 0;
drh.khtml = (dav.indexOf("Konqueror") >= 0)||(dav.indexOf("Safari") >= 0);
drh.safari = dav.indexOf("Safari") >= 0;
var geckoPos = dua.indexOf("Gecko");
drh.mozilla = drh.moz = (geckoPos >= 0)&&(!drh.khtml);
if (drh.mozilla) {
// gecko version is YYYYMMDD
drh.geckoVersion = dua.substring(geckoPos + 6, geckoPos + 14);
}
drh.ie = (document.all)&&(!drh.opera);
drh.ie50 = drh.ie && dav.indexOf("MSIE 5.0")>=0;
drh.ie55 = drh.ie && dav.indexOf("MSIE 5.5")>=0;
drh.ie60 = drh.ie && dav.indexOf("MSIE 6.0")>=0;
drh.ie70 = drh.ie && dav.indexOf("MSIE 7.0")>=0;
// TODO: is the HTML LANG attribute relevant?
dojo.locale = (drh.ie ? navigator.userLanguage : navigator.language).toLowerCase();
dr.vml.capable=drh.ie;
drs.capable = f;
drs.support.plugin = f;
drs.support.builtin = f;
if (document.implementation
&& document.implementation.hasFeature
&& document.implementation.hasFeature("org.w3c.dom.svg", "1.0")
){
drs.capable = t;
drs.support.builtin = t;
drs.support.plugin = f;
}
})();
dojo.hostenv.startPackage("dojo.hostenv");
dojo.render.name = dojo.hostenv.name_ = 'browser';
dojo.hostenv.searchIds = [];
// These are in order of decreasing likelihood; this will change in time.
dojo.hostenv._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
dojo.hostenv.getXmlhttpObject = function(){
var http = null;
var last_e = null;
try{ http = new XMLHttpRequest(); }catch(e){}
if(!http){
for(var i=0; i<3; ++i){
var progid = dojo.hostenv._XMLHTTP_PROGIDS[i];
try{
http = new ActiveXObject(progid);
}catch(e){
last_e = e;
}
if(http){
dojo.hostenv._XMLHTTP_PROGIDS = [progid]; // so faster next time
break;
}
}
/*if(http && !http.toString) {
http.toString = function() { "[object XMLHttpRequest]"; }
}*/
}
if(!http){
return dojo.raise("XMLHTTP not available", last_e);
}
return http;
}
/**
* Read the contents of the specified uri and return those contents.
*
* @param uri A relative or absolute uri. If absolute, it still must be in the
* same "domain" as we are.
*
* @param async_cb If not specified, load synchronously. If specified, load
* asynchronously, and use async_cb as the progress handler which takes the
* xmlhttp object as its argument. If async_cb, this function returns null.
*
* @param fail_ok Default false. If fail_ok and !async_cb and loading fails,
* return null instead of throwing.
*/
dojo.hostenv.getText = function(uri, async_cb, fail_ok){
var http = this.getXmlhttpObject();
if(async_cb){
http.onreadystatechange = function(){
if(4==http.readyState){
if((!http["status"])||((200 <= http.status)&&(300 > http.status))){
// dojo.debug("LOADED URI: "+uri);
async_cb(http.responseText);
}
}
}
}
http.open('GET', uri, async_cb ? true : false);
try{
http.send(null);
if(async_cb){
return null;
}
if((http["status"])&&((200 > http.status)||(300 <= http.status))){
throw Error("Unable to load "+uri+" status:"+ http.status);
}
}catch(e){
if((fail_ok)&&(!async_cb)){
return null;
}else{
throw e;
}
}
return http.responseText;
}
/*
* It turns out that if we check *right now*, as this script file is being loaded,
* then the last script element in the window DOM is ourselves.
* That is because any subsequent script elements haven't shown up in the document
* object yet.
*/
/*
function dj_last_script_src() {
var scripts = window.document.getElementsByTagName('script');
if(scripts.length < 1){
dojo.raise("No script elements in window.document, so can't figure out my script src");
}
var script = scripts[scripts.length - 1];
var src = script.src;
if(!src){
dojo.raise("Last script element (out of " + scripts.length + ") has no src");
}
return src;
}
if(!dojo.hostenv["library_script_uri_"]){
dojo.hostenv.library_script_uri_ = dj_last_script_src();
}
*/
dojo.hostenv.defaultDebugContainerId = 'dojoDebug';
dojo.hostenv._println_buffer = [];
dojo.hostenv._println_safe = false;
dojo.hostenv.println = function (line){
if(!dojo.hostenv._println_safe){
dojo.hostenv._println_buffer.push(line);
}else{
try {
var console = document.getElementById(djConfig.debugContainerId ?
djConfig.debugContainerId : dojo.hostenv.defaultDebugContainerId);
if(!console) { console = document.getElementsByTagName("body")[0] || document.body; }
var div = document.createElement("div");
div.appendChild(document.createTextNode(line));
console.appendChild(div);
} catch (e) {
try{
// safari needs the output wrapped in an element for some reason
document.write("<div>" + line + "</div>");
}catch(e2){
window.status = line;
}
}
}
}
dojo.addOnLoad(function(){
dojo.hostenv._println_safe = true;
while(dojo.hostenv._println_buffer.length > 0){
dojo.hostenv.println(dojo.hostenv._println_buffer.shift());
}
});
function dj_addNodeEvtHdlr(node, evtName, fp, capture){
var oldHandler = node["on"+evtName] || function(){};
node["on"+evtName] = function(){
fp.apply(node, arguments);
oldHandler.apply(node, arguments);
}
return true;
}
/* Uncomment this to allow init after DOMLoad, not after window.onload
// Mozilla exposes the event we could use
if (dojo.render.html.mozilla) {
document.addEventListener("DOMContentLoaded", dj_load_init, null);
}
// for Internet Explorer. readyState will not be achieved on init call, but dojo doesn't need it
//Tighten up the comments below to allow init after DOMLoad, not after window.onload
/ * @cc_on @ * /
/ * @if (@_win32)
document.write("<script defer>dj_load_init()<"+"/script>");
/ * @end @ * /
*/
// default for other browsers
// potential TODO: apply setTimeout approach for other browsers
// that will cause flickering though ( document is loaded and THEN is processed)
// maybe show/hide required in this case..
// TODO: other browsers may support DOMContentLoaded/defer attribute. Add them to above.
dj_addNodeEvtHdlr(window, "load", function(){
// allow multiple calls, only first one will take effect
if(arguments.callee.initialized){ return; }
arguments.callee.initialized = true;
var initFunc = function(){
//perform initialization
if(dojo.render.html.ie){
dojo.hostenv.makeWidgets();
}
};
if(dojo.hostenv.inFlightCount == 0){
initFunc();
dojo.hostenv.modulesLoaded();
}else{
dojo.addOnLoad(initFunc);
}
});
dj_addNodeEvtHdlr(window, "unload", function(){
dojo.hostenv.unloaded();
});
dojo.hostenv.makeWidgets = function(){
// you can put searchIds in djConfig and dojo.hostenv at the moment
// we should probably eventually move to one or the other
var sids = [];
if(djConfig.searchIds && djConfig.searchIds.length > 0) {
sids = sids.concat(djConfig.searchIds);
}
if(dojo.hostenv.searchIds && dojo.hostenv.searchIds.length > 0) {
sids = sids.concat(dojo.hostenv.searchIds);
}
if((djConfig.parseWidgets)||(sids.length > 0)){
if(dojo.evalObjPath("dojo.widget.Parse")){
// we must do this on a delay to avoid:
// http://www.shaftek.org/blog/archives/000212.html
// IE is such a tremendous peice of shit.
var parser = new dojo.xml.Parse();
if(sids.length > 0){
for(var x=0; x<sids.length; x++){
var tmpNode = document.getElementById(sids[x]);
if(!tmpNode){ continue; }
var frag = parser.parseElement(tmpNode, null, true);
dojo.widget.getParser().createComponents(frag);
}
}else if(djConfig.parseWidgets){
var frag = parser.parseElement(document.getElementsByTagName("body")[0] || document.body, null, true);
dojo.widget.getParser().createComponents(frag);
}
}
}
}
dojo.addOnLoad(function(){
if(!dojo.render.html.ie) {
dojo.hostenv.makeWidgets();
}
});
try {
if (dojo.render.html.ie) {
document.write('<style>v\:*{ behavior:url(#default#VML); }</style>');
document.write('<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v"/>');
}
} catch (e) { }
// stub, over-ridden by debugging code. This will at least keep us from
// breaking when it's not included
dojo.hostenv.writeIncludes = function(){}
dojo.byId = function(id, doc){
if(id && (typeof id == "string" || id instanceof String)){
if(!doc){ doc = document; }
return doc.getElementById(id);
}
return id; // assume it's a node
}

View file

@ -0,0 +1,197 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.render.name = dojo.hostenv.name_ = "dashboard";
dojo.hostenv.println = function(/*String*/ message){
// summary: Prints a message to the OS X console
return alert(message); // null
}
dojo.hostenv.getXmlhttpObject = function(/*Object*/ kwArgs){
// summary: Returns the appropriate transfer object for the call type
if(widget.system && kwArgs){
if((kwArgs.contentType && kwArgs.contentType.indexOf("text/") != 0) || (kwArgs.headers && kwArgs.headers["content-type"] && kwArgs.headers["content-type"].indexOf("text/") != 0)){
var curl = new dojo.hostenv.CurlRequest;
curl._save = true;
return curl;
}else if(kwArgs.method && kwArgs.method.toUpperCase() == "HEAD"){
return new dojo.hostenv.CurlRequest;
}else if(kwArgs.headers && kwArgs.header.referer){
return new dojo.hostenv.CurlRequest;
}
}
return new XMLHttpRequest; // XMLHttpRequest
}
dojo.hostenv.CurlRequest = function(){
// summary: Emulates the XMLHttpRequest Object
this.onreadystatechange = null;
this.readyState = 0;
this.responseText = "";
this.responseXML = null;
this.status = 0;
this.statusText = "";
this._method = "";
this._url = "";
this._async = true;
this._referrer = "";
this._headers = [];
this._save = false;
this._responseHeader = "";
this._responseHeaders = {};
this._fileName = "";
this._username = "";
this._password = "";
}
dojo.hostenv.CurlRequest.prototype.open = function(/*String*/ method, /*URL*/ url, /*Boolean?*/ async, /*String?*/ username, /*String?*/ password){
this._method = method;
this._url = url;
if(async){
this._async = async;
}
if(username){
this._username = username;
}
if(password){
this._password = password;
}
}
dojo.hostenv.CurlRequest.prototype.setRequestHeader = function(/*String*/ label, /*String*/ value){
switch(label){
case "Referer":
this._referrer = value;
break;
case "content-type":
break;
default:
this._headers.push(label + "=" + value);
break;
}
}
dojo.hostenv.CurlRequest.prototype.getAllResponseHeaders = function(){
return this._responseHeader; // String
}
dojo.hostenv.CurlRequest.prototype.getResponseHeader = function(/*String*/ headerLabel){
return this._responseHeaders[headerLabel]; // String
}
// -sS = Show only errors in errorString
// -i = Display headers with return
// -e = Referrer URI
// -H = Headers
// -d = data to be sent (forces POST)
// -G = forces GET
// -o = Writes to file (in the cache directory)
// -I = Only load headers
// -u = user:password
dojo.hostenv.CurlRequest.prototype.send = function(/*String*/ content){
this.readyState = 1;
if(this.onreadystatechange){
this.onreadystatechange.call(this);
}
var query = {sS: ""};
if(this._referrer){
query.e = this._referrer;
}
if(this._headers.length){
query.H = this._headers.join("&");
}
if(this._username){
if(this._password){
query.u = this._username + ":" + this._password;
}else{
query.u = this._username;
}
}
if(content){
query.d = this.content;
if(this._method != "POST"){
query.G = "";
}
}
if(this._method == "HEAD"){
query.I = "";
}else{
if(this._save){
query.I = ""; // Get the headers in the initial query
}else{
query.i = "";
}
}
var system = widget.system(dojo.hostenv.CurlRequest._formatCall(query, this._url), null);
this.readyState = 2;
if(this.onreadystatechange){
this.onreadystatechange.call(this);
}
if(system.errorString){
this.responseText = system.errorString;
this.status = 0;
}else{
if(this._save){
this._responseHeader = system.outputString;
}else{
var split = system.outputString.replace(/\r/g, "").split("\n\n", 2);
this._responseHeader = split[0];
this.responseText = split[1];
}
split = this._responseHeader.split("\n");
this.statusText = split.shift();
this.status = this.statusText.split(" ")[1];
for(var i = 0, header; header = split[i]; i++){
var header_split = header.split(": ", 2);
this._responseHeaders[header_split[0]] = header_split[1];
}
if(this._save){
widget.system("/bin/mkdir cache", null);
// First, make a file name
this._fileName = this._url.split("/").pop().replace(/\W/g, "");
// Then, get its extension
this._fileName += "." + this._responseHeaders["Content-Type"].replace(/[\r\n]/g, "").split("/").pop()
delete query.I;
query.o = "cache/" + this._fileName; // Tell it where to be saved.
system = widget.system(dojo.hostenv.CurlRequest._formatCall(query, this._url), null);
if(!system.errorString){
this.responseText = "cache/" + this._fileName;
}
}else if(this._method == "HEAD"){
this.responseText = this._responseHeader;
}
}
this.readyState = 4;
if(this.onreadystatechange){
this.onreadystatechange.call(this);
}
}
dojo.hostenv.CurlRequest._formatCall = function(query, url){
var call = ["/usr/bin/curl"];
for(var key in query){
if(query[key] != ""){
call.push("-" + key + " '" + query[key].replace(/'/g, "\'") + "'");
}else{
call.push("-" + key);
}
}
call.push("'" + url.replace(/'/g, "\'") + "'");
return call.join(" ");
}
dojo.hostenv.exit = function(){
if(widget.system){
widget.system("/bin/rm -rf cache/*", null);
}
}

View file

@ -0,0 +1,76 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/*
* JScript .NET jsc
*
*/
dojo.hostenv.name_ = 'jsc';
// Sanity check this is the right hostenv.
// See the Rotor source code jscript/engine/globalobject.cs for what globals
// are available.
if((typeof ScriptEngineMajorVersion != 'function')||(ScriptEngineMajorVersion() < 7)){
dojo.raise("attempt to use JScript .NET host environment with inappropriate ScriptEngine");
}
// for more than you wanted to know about why this import is required even if
// we fully qualify all symbols, see
// http://groups.google.com/groups?th=f050c7aeefdcbde2&rnum=12
import System;
dojo.hostenv.getText = function(uri){
if(!System.IO.File.Exists(uri)){
// dojo.raise("No such file '" + uri + "'");
return 0;
}
var reader = new System.IO.StreamReader(uri);
var contents : String = reader.ReadToEnd();
return contents;
}
dojo.hostenv.loadUri = function(uri){
var contents = this.getText(uri);
if(!contents){
dojo.raise("got no back contents from uri '" + uri + "': " + contents);
}
// TODO: in JScript .NET, eval will not affect the symbol table of the current code?
var value = dj_eval(contents);
dojo.debug("jsc eval of contents returned: ", value);
return 1;
// for an example doing runtime code compilation, see:
// http://groups.google.com/groups?selm=eQ1aeciCBHA.1644%40tkmsftngp05&rnum=6
// Microsoft.JScript or System.CodeDom.Compiler ?
// var engine = new Microsoft.JScript.Vsa.VsaEngine()
// what about loading a js file vs. a dll?
// GetObject("script:" . uri);
}
/* The System.Environment object is useful:
print ("CommandLine='" + System.Environment.CommandLine + "' " +
"program name='" + System.Environment.GetCommandLineArgs()[0] + "' " +
"CurrentDirectory='" + System.Environment.CurrentDirectory + "' " +
"StackTrace='" + System.Environment.StackTrace + "'");
*/
// same as System.Console.WriteLine
// sigh; Rotor treats symbol "print" at parse time without actually putting it
// in the builtin symbol table.
// Note that the print symbol is not available if jsc is run with the "/print-"
// option.
dojo.hostenv.println = function(s){
print(s); // = print
}
dojo.hostenv.getLibraryScriptUri = function(){
return System.Environment.GetCommandLineArgs()[0];
}

View file

@ -0,0 +1,190 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/*
* Rhino host environment
*/
// make jsc shut up (so we can use jsc for sanity checking)
/*@cc_on
@if (@_jscript_version >= 7)
var loadClass; var print; var load; var quit; var version; var Packages; var java;
@end
@*/
// TODO: not sure what we gain from the next line, anyone?
//if (typeof loadClass == 'undefined') { dojo.raise("attempt to use Rhino host environment when no 'loadClass' global"); }
dojo.render.name = dojo.hostenv.name_ = 'rhino';
dojo.hostenv.getVersion = function() {return version()};
// see comments in spidermonkey loadUri
dojo.hostenv.loadUri = function(uri, cb){
dojo.debug("uri: "+uri);
try{
// FIXME: what about remote URIs?
var found = true;
if(!(new java.io.File(uri)).exists()){
try{
// try it as a file first, URL second
(new java.io.URL(uri)).openStream();
}catch(e){
found = false;
}
}
if(!found){
dojo.debug(uri+" does not exist");
if(cb){ cb(0); }
return 0;
}
var ok = load(uri);
// dojo.debug(typeof ok);
dojo.debug("rhino load('", uri, "') returned. Ok: ", ok);
if(cb){ cb(1); }
return 1;
}catch(e){
dojo.debug("rhino load('", uri, "') failed");
if(cb){ cb(0); }
return 0;
}
}
dojo.hostenv.println = print;
dojo.hostenv.exit = function(exitcode){
quit(exitcode);
}
// Hack to determine current script...
//
// These initial attempts failed:
// 1. get an EcmaError and look at e.getSourceName(): try {eval ("static in return")} catch(e) { ...
// Won't work because NativeGlobal.java only does a put of "name" and "message", not a wrapped reflecting object.
// Even if the EcmaError object had the sourceName set.
//
// 2. var e = Packages.org.mozilla.javascript.Context.getCurrentContext().reportError('');
// Won't work because it goes directly to the errorReporter, not the return value.
// We want context.interpreterSourceFile and context.interpreterLine, which are used in static Context.getSourcePositionFromStack
// (set by Interpreter.java at interpretation time, if in interpreter mode).
//
// 3. var e = Packages.org.mozilla.javascript.Context.getCurrentContext().reportRuntimeError('');
// This returns an object, but e.message still does not have source info.
// In compiler mode, perhaps not set; in interpreter mode, perhaps not used by errorReporter?
//
// What we found works is to do basically the same hack as is done in getSourcePositionFromStack,
// making a new java.lang.Exception() and then calling printStackTrace on a string stream.
// We have to parse the string for the .js files (different from the java files).
// This only works however in compiled mode (-opt 0 or higher).
// In interpreter mode, entire stack is java.
// When compiled, printStackTrace is like:
// java.lang.Exception
// at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
// at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
// at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
// at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
// at org.mozilla.javascript.NativeJavaClass.constructSpecific(NativeJavaClass.java:228)
// at org.mozilla.javascript.NativeJavaClass.construct(NativeJavaClass.java:185)
// at org.mozilla.javascript.ScriptRuntime.newObject(ScriptRuntime.java:1269)
// at org.mozilla.javascript.gen.c2.call(/Users/mda/Sites/burstproject/testrhino.js:27)
// ...
// at org.mozilla.javascript.tools.shell.Main.main(Main.java:76)
//
// Note may get different answers based on:
// Context.setOptimizationLevel(-1)
// Context.setGeneratingDebug(true)
// Context.setGeneratingSource(true)
//
// Some somewhat helpful posts:
// http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=9v9n0g%246gr1%40ripley.netscape.com
// http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=3BAA2DC4.6010702%40atg.com
//
// Note that Rhino1.5R5 added source name information in some exceptions.
// But this seems not to help in command-line Rhino, because Context.java has an error reporter
// so no EvaluationException is thrown.
// do it by using java java.lang.Exception
function dj_rhino_current_script_via_java(depth) {
var optLevel = Packages.org.mozilla.javascript.Context.getCurrentContext().getOptimizationLevel();
if (optLevel == -1) dojo.unimplemented("getCurrentScriptURI (determine current script path for rhino when interpreter mode)", '');
var caw = new java.io.CharArrayWriter();
var pw = new java.io.PrintWriter(caw);
var exc = new java.lang.Exception();
var s = caw.toString();
// we have to exclude the ones with or without line numbers because they put double entries in:
// at org.mozilla.javascript.gen.c3._c4(/Users/mda/Sites/burstproject/burst/Runtime.js:56)
// at org.mozilla.javascript.gen.c3.call(/Users/mda/Sites/burstproject/burst/Runtime.js)
var matches = s.match(/[^\(]*\.js\)/gi);
if(!matches){
throw Error("cannot parse printStackTrace output: " + s);
}
// matches[0] is entire string, matches[1] is this function, matches[2] is caller, ...
var fname = ((typeof depth != 'undefined')&&(depth)) ? matches[depth + 1] : matches[matches.length - 1];
var fname = matches[3];
if(!fname){ fname = matches[1]; }
// print("got fname '" + fname + "' from stack string '" + s + "'");
if (!fname) throw Error("could not find js file in printStackTrace output: " + s);
//print("Rhino getCurrentScriptURI returning '" + fname + "' from: " + s);
return fname;
}
// UNUSED: leverage new support in native exception for getSourceName
/*
function dj_rhino_current_script_via_eval_exception() {
var exc;
// 'ReferenceError: "undefinedsymbol" is not defined.'
try {eval ("undefinedsymbol()") } catch(e) {exc = e;}
// 'Error: whatever'
// try{throw Error("whatever");} catch(e) {exc = e;}
// 'SyntaxError: identifier is a reserved word'
// try {eval ("static in return")} catch(e) { exc = e; }
print("got exception: '" + exc + "'");
print("exc.stack=" + (typeof exc.stack));
var sn = exc.getSourceName();
print("SourceName=" + sn);
return sn;
}
*/
// reading a file from disk in Java is a humiliating experience by any measure.
// Lets avoid that and just get the freaking text
function readText(uri){
// NOTE: we intentionally avoid handling exceptions, since the caller will
// want to know
var jf = new java.io.File(uri);
var sb = new java.lang.StringBuffer();
var input = new java.io.BufferedReader(new java.io.FileReader(jf));
var line = "";
while((line = input.readLine()) != null){
sb.append(line);
sb.append(java.lang.System.getProperty("line.separator"));
}
return sb.toString();
}
// call this now because later we may not be on the top of the stack
if(!djConfig.libraryScriptUri.length){
try{
djConfig.libraryScriptUri = dj_rhino_current_script_via_java(1);
}catch(e){
// otherwise just fake it
if(djConfig["isDebug"]){
print("\n");
print("we have no idea where Dojo is located from.");
print("Please try loading rhino in a non-interpreted mode or set a");
print("\n djConfig.libraryScriptUri\n");
print("Setting the dojo path to './'");
print("This is probably wrong!");
print("\n");
print("Dojo will try to load anyway");
}
djConfig.libraryScriptUri = "./";
}
}

View file

@ -0,0 +1,79 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/*
* SpiderMonkey host environment
*/
dojo.hostenv.name_ = 'spidermonkey';
dojo.hostenv.println = print;
dojo.hostenv.exit = function(exitcode){
quit(exitcode);
}
// version() returns 0, sigh. and build() returns nothing but just prints.
dojo.hostenv.getVersion = function(){ return version(); }
// make jsc shut up (so we can use jsc for sanity checking)
/*@cc_on
@if (@_jscript_version >= 7)
var line2pc; var print; var load; var quit;
@end
@*/
if(typeof line2pc == 'undefined'){
dojo.raise("attempt to use SpiderMonkey host environment when no 'line2pc' global");
}
/*
* This is a hack that determines the current script file by parsing a generated
* stack trace (relying on the non-standard "stack" member variable of the
* SpiderMonkey Error object).
* If param depth is passed in, it'll return the script file which is that far down
* the stack, but that does require that you know how deep your stack is when you are
* calling.
*/
function dj_spidermonkey_current_file(depth){
var s = '';
try{
throw Error("whatever");
}catch(e){
s = e.stack;
}
// lines are like: bu_getCurrentScriptURI_spidermonkey("ScriptLoader.js")@burst/Runtime.js:101
var matches = s.match(/[^@]*\.js/gi);
if(!matches){
dojo.raise("could not parse stack string: '" + s + "'");
}
var fname = (typeof depth != 'undefined' && depth) ? matches[depth + 1] : matches[matches.length - 1];
if(!fname){
dojo.raise("could not find file name in stack string '" + s + "'");
}
//print("SpiderMonkeyRuntime got fname '" + fname + "' from stack string '" + s + "'");
return fname;
}
// call this now because later we may not be on the top of the stack
if(!dojo.hostenv.library_script_uri_){
dojo.hostenv.library_script_uri_ = dj_spidermonkey_current_file(0);
}
dojo.hostenv.loadUri = function(uri){
// spidermonkey load() evaluates the contents into the global scope (which
// is what we want).
// TODO: sigh, load() does not return a useful value.
// Perhaps it is returning the value of the last thing evaluated?
var ok = load(uri);
// dojo.debug("spidermonkey load(", uri, ") returned ", ok);
return 1;
}

View file

@ -0,0 +1,223 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
// hostenv_svg
if(typeof window == 'undefined'){
dojo.raise("attempt to use adobe svg hostenv when no window object");
}
dojo.debug = function(){
if (!djConfig.isDebug) { return; }
var args = arguments;
var isJUM = dj_global["jum"];
var s = isJUM ? "": "DEBUG: ";
for (var i = 0; i < args.length; ++i){ s += args[i]; }
if (isJUM){ // this seems to be the only way to get JUM to "play nice"
jum.debug(s);
} else{
dojo.hostenv.println(s);
}
};
// set up dojo.render.
dojo.render.name = navigator.appName;
dojo.render.ver = parseFloat(navigator.appVersion, 10);
switch(navigator.platform){
case "MacOS":
dojo.render.os.osx = true;
break;
case "Linux":
dojo.render.os.linux = true;
break;
case "Windows":
dojo.render.os.win = true;
break;
default:
dojo.render.os.linux = true;
break;
};
dojo.render.svg.capable = true;
dojo.render.svg.support.builtin = true;
// FIXME the following two is a big-ass hack for now.
dojo.render.svg.moz = ((navigator.userAgent.indexOf("Gecko") >= 0) && (!((navigator.appVersion.indexOf("Konqueror") >= 0) || (navigator.appVersion.indexOf("Safari") >= 0))));
dojo.render.svg.adobe = (window.parseXML != null);
// agent-specific implementations.
// from old hostenv_adobesvg.
dojo.hostenv.startPackage("dojo.hostenv");
dojo.hostenv.println = function(s){
try {
var ti = document.createElement("text");
ti.setAttribute("x","50");
ti.setAttribute("y", (25 + 15 * document.getElementsByTagName("text").length));
ti.appendChild(document.createTextNode(s));
document.documentElement.appendChild(ti);
} catch(e){ }
};
dojo.hostenv.name_ = "svg";
// expected/defined by bootstrap1.js
dojo.hostenv.setModulePrefix = function(module, prefix){ };
dojo.hostenv.getModulePrefix = function(module){ };
dojo.hostenv.getTextStack = [];
dojo.hostenv.loadUriStack = [];
dojo.hostenv.loadedUris = [];
dojo.hostenv.modules_ = {};
dojo.hostenv.modulesLoadedFired = false;
dojo.hostenv.modulesLoadedListeners = [];
dojo.hostenv.getText = function(uri, cb, data){
if (!cb) var cb = function(result){ window.alert(result); };
if (!data) {
window.getUrl(uri, cb);
} else {
window.postUrl(uri, data, cb);
}
};
dojo.hostenv.getLibaryScriptUri = function(){ };
dojo.hostenv.loadUri = function(uri){ };
dojo.hostenv.loadUriAndCheck = function(uri, module){ };
// aliased in loader.js, don't ignore
// we are going to kill loadModule for the first round of SVG stuff, and include shit manually.
dojo.hostenv.loadModule = function(moduleName){
// just like startPackage, but this time we're just checking to make sure it exists already.
var a = moduleName.split(".");
var currentObj = window;
var s = [];
for (var i = 0; i < a.length; i++){
if (a[i] == "*") continue;
s.push(a[i]);
if (!currentObj[a[i]]){
dojo.raise("dojo.require('" + moduleName + "'): module does not exist.");
} else currentObj = currentObj[a[i]];
}
return;
};
dojo.hostenv.startPackage = function(moduleName){
var a = moduleName.split(".");
var currentObj = window;
var s = [];
for (var i = 0; i < a.length; i++){
if (a[i] == "*") continue;
s.push(a[i]);
if (!currentObj[a[i]]) currentObj[a[i]] = {};
currentObj = currentObj[a[i]];
}
return;
};
// wrapper objects for ASVG
if (window.parseXML){
window.XMLSerialzer = function(){
// based on WebFX RichTextControl getXHTML() function.
function nodeToString(n, a) {
function fixText(s) { return String(s).replace(/\&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;"); }
function fixAttribute(s) { return fixText(s).replace(/\"/g, "&quot;"); }
switch (n.nodeType) {
case 1: { // ELEMENT
var name = n.nodeName;
a.push("<" + name);
for (var i = 0; i < n.attributes.length; i++) {
if (n.attributes.item(i).specified) {
a.push(" " + n.attributes.item(i).nodeName.toLowerCase() + "=\"" + fixAttribute(n.attributes.item(i).nodeValue) + "\"");
}
}
if (n.canHaveChildren || n.hasChildNodes()) {
a.push(">");
for (var i = 0; i < n.childNodes.length; i++) nodeToString(n.childNodes.item(i), a);
a.push("</" + name + ">\n");
} else a.push(" />\n");
break;
}
case 3: { // TEXT
a.push(fixText(n.nodeValue));
break;
}
case 4: { // CDATA
a.push("<![CDA" + "TA[\n" + n.nodeValue + "\n]" + "]>");
break;
}
case 7:{ // PROCESSING INSTRUCTION
a.push(n.nodeValue);
if (/(^<\?xml)|(^<\!DOCTYPE)/.test(n.nodeValue)) a.push("\n");
break;
}
case 8:{ // COMMENT
a.push("<!-- " + n.nodeValue + " -->\n");
break;
}
case 9: // DOCUMENT
case 11:{ // DOCUMENT FRAGMENT
for (var i = 0; i < n.childNodes.length; i++) nodeToString(n.childNodes.item(i), a);
break;
}
default:{
a.push("<!--\nNot Supported:\n\n" + "nodeType: " + n.nodeType + "\nnodeName: " + n.nodeName + "\n-->");
}
}
}
this.serializeToString = function(node){
var a = [];
nodeToString(node, a);
return a.join("");
};
};
window.DOMParser = function(){
// mimetype is basically ignored
this.parseFromString = function(s){
return parseXML(s, window.document);
}
};
window.XMLHttpRequest = function(){
// we ignore the setting and getting of content-type.
var uri = null;
var method = "POST";
var isAsync = true;
var cb = function(d){
this.responseText = d.content;
try {
this.responseXML = parseXML(this.responseText, window.document);
} catch(e){}
this.status = "200";
this.statusText = "OK";
if (!d.success) {
this.status = "500";
this.statusText = "Internal Server Error";
}
this.onload();
this.onreadystatechange();
};
this.onload = function(){};
this.readyState = 4;
this.onreadystatechange = function(){};
this.status = 0;
this.statusText = "";
this.responseBody = null;
this.responseStream = null;
this.responseXML = null;
this.responseText = null;
this.abort = function(){ return; };
this.getAllResponseHeaders = function(){ return []; };
this.getResponseHeader = function(n){ return null; };
this.setRequestHeader = function(nm, val){ };
this.open = function(meth, url, async){
method = meth;
uri = url;
};
this.send = function(data){
var d = data || null;
if (method == "GET") getURL(uri, cb);
else postURL(uri, data, cb);
};
};
}

View file

@ -0,0 +1,46 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
/*
* WSH
*/
dojo.hostenv.name_ = 'wsh';
// make jsc shut up (so can sanity check)
/*@cc_on
@if (@_jscript_version >= 7)
var WScript;
@end
@*/
// make sure we are in right environment
if(typeof WScript == 'undefined'){
dojo.raise("attempt to use WSH host environment when no WScript global");
}
dojo.hostenv.println = WScript.Echo;
dojo.hostenv.getCurrentScriptUri = function(){
return WScript.ScriptFullName();
}
dojo.hostenv.getText = function(fpath){
var fso = new ActiveXObject("Scripting.FileSystemObject");
var istream = fso.OpenTextFile(fpath, 1); // iomode==1 means read only
if(!istream){
return null;
}
var contents = istream.ReadAll();
istream.Close();
return contents;
}
dojo.hostenv.exit = function(exitcode){ WScript.Quit(exitcode); }

595
webapp/web/src/html.js Normal file
View file

@ -0,0 +1,595 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html");
dojo.require("dojo.lang.func");
dojo.require("dojo.dom");
dojo.require("dojo.style");
dojo.require("dojo.string");
dojo.lang.mixin(dojo.html, dojo.dom);
dojo.lang.mixin(dojo.html, dojo.style);
// FIXME: we are going to assume that we can throw any and every rendering
// engine into the IE 5.x box model. In Mozilla, we do this w/ CSS.
// Need to investigate for KHTML and Opera
dojo.html.clearSelection = function(){
try{
if(window["getSelection"]){
if(dojo.render.html.safari){
// pulled from WebCore/ecma/kjs_window.cpp, line 2536
window.getSelection().collapse();
}else{
window.getSelection().removeAllRanges();
}
}else if(document.selection){
if(document.selection.empty){
document.selection.empty();
}else if(document.selection.clear){
document.selection.clear();
}
}
return true;
}catch(e){
dojo.debug(e);
return false;
}
}
dojo.html.disableSelection = function(element){
element = dojo.byId(element)||document.body;
var h = dojo.render.html;
if(h.mozilla){
element.style.MozUserSelect = "none";
}else if(h.safari){
element.style.KhtmlUserSelect = "none";
}else if(h.ie){
element.unselectable = "on";
}else{
return false;
}
return true;
}
dojo.html.enableSelection = function(element){
element = dojo.byId(element)||document.body;
var h = dojo.render.html;
if(h.mozilla){
element.style.MozUserSelect = "";
}else if(h.safari){
element.style.KhtmlUserSelect = "";
}else if(h.ie){
element.unselectable = "off";
}else{
return false;
}
return true;
}
dojo.html.selectElement = function(element){
element = dojo.byId(element);
if(document.selection && document.body.createTextRange){ // IE
var range = document.body.createTextRange();
range.moveToElementText(element);
range.select();
}else if(window["getSelection"]){
var selection = window.getSelection();
// FIXME: does this work on Safari?
if(selection["selectAllChildren"]){ // Mozilla
selection.selectAllChildren(element);
}
}
}
dojo.html.selectInputText = function(element){
element = dojo.byId(element);
if(document.selection && document.body.createTextRange){ // IE
var range = element.createTextRange();
range.moveStart("character", 0);
range.moveEnd("character", element.value.length);
range.select();
}else if(window["getSelection"]){
var selection = window.getSelection();
// FIXME: does this work on Safari?
element.setSelectionRange(0, element.value.length);
}
element.focus();
}
dojo.html.isSelectionCollapsed = function(){
if(document["selection"]){ // IE
return document.selection.createRange().text == "";
}else if(window["getSelection"]){
var selection = window.getSelection();
if(dojo.lang.isString(selection)){ // Safari
return selection == "";
}else{ // Mozilla/W3
return selection.isCollapsed;
}
}
}
dojo.html.getEventTarget = function(evt){
if(!evt) { evt = window.event || {} };
var t = (evt.srcElement ? evt.srcElement : (evt.target ? evt.target : null));
while((t)&&(t.nodeType!=1)){ t = t.parentNode; }
return t;
}
dojo.html.getDocumentWidth = function(){
dojo.deprecated("dojo.html.getDocument*", "replaced by dojo.html.getViewport*", "0.4");
return dojo.html.getViewportWidth();
}
dojo.html.getDocumentHeight = function(){
dojo.deprecated("dojo.html.getDocument*", "replaced by dojo.html.getViewport*", "0.4");
return dojo.html.getViewportHeight();
}
dojo.html.getDocumentSize = function(){
dojo.deprecated("dojo.html.getDocument*", "replaced of dojo.html.getViewport*", "0.4");
return dojo.html.getViewportSize();
}
dojo.html.getViewportWidth = function(){
var w = 0;
if(window.innerWidth){
w = window.innerWidth;
}
if(dojo.exists(document, "documentElement.clientWidth")){
// IE6 Strict
var w2 = document.documentElement.clientWidth;
// this lets us account for scrollbars
if(!w || w2 && w2 < w) {
w = w2;
}
return w;
}
if(document.body){
// IE
return document.body.clientWidth;
}
return 0;
}
dojo.html.getViewportHeight = function(){
if (window.innerHeight){
return window.innerHeight;
}
if (dojo.exists(document, "documentElement.clientHeight")){
// IE6 Strict
return document.documentElement.clientHeight;
}
if (document.body){
// IE
return document.body.clientHeight;
}
return 0;
}
dojo.html.getViewportSize = function(){
var ret = [dojo.html.getViewportWidth(), dojo.html.getViewportHeight()];
ret.w = ret[0];
ret.h = ret[1];
return ret;
}
dojo.html.getScrollTop = function(){
return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
}
dojo.html.getScrollLeft = function(){
return window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
}
dojo.html.getScrollOffset = function(){
var off = [dojo.html.getScrollLeft(), dojo.html.getScrollTop()];
off.x = off[0];
off.y = off[1];
return off;
}
dojo.html.getParentOfType = function(node, type){
dojo.deprecated("dojo.html.getParentOfType", "replaced by dojo.html.getParentByType*", "0.4");
return dojo.html.getParentByType(node, type);
}
dojo.html.getParentByType = function(node, type) {
var parent = dojo.byId(node);
type = type.toLowerCase();
while((parent)&&(parent.nodeName.toLowerCase()!=type)){
if(parent==(document["body"]||document["documentElement"])){
return null;
}
parent = parent.parentNode;
}
return parent;
}
// RAR: this function comes from nwidgets and is more-or-less unmodified.
// We should probably look ant Burst and f(m)'s equivalents
dojo.html.getAttribute = function(node, attr){
node = dojo.byId(node);
// FIXME: need to add support for attr-specific accessors
if((!node)||(!node.getAttribute)){
// if(attr !== 'nwType'){
// alert("getAttr of '" + attr + "' with bad node");
// }
return null;
}
var ta = typeof attr == 'string' ? attr : new String(attr);
// first try the approach most likely to succeed
var v = node.getAttribute(ta.toUpperCase());
if((v)&&(typeof v == 'string')&&(v!="")){ return v; }
// try returning the attributes value, if we couldn't get it as a string
if(v && v.value){ return v.value; }
// this should work on Opera 7, but it's a little on the crashy side
if((node.getAttributeNode)&&(node.getAttributeNode(ta))){
return (node.getAttributeNode(ta)).value;
}else if(node.getAttribute(ta)){
return node.getAttribute(ta);
}else if(node.getAttribute(ta.toLowerCase())){
return node.getAttribute(ta.toLowerCase());
}
return null;
}
/**
* Determines whether or not the specified node carries a value for the
* attribute in question.
*/
dojo.html.hasAttribute = function(node, attr){
node = dojo.byId(node);
return dojo.html.getAttribute(node, attr) ? true : false;
}
/**
* Returns the string value of the list of CSS classes currently assigned
* directly to the node in question. Returns an empty string if no class attribute
* is found;
*/
dojo.html.getClass = function(node){
node = dojo.byId(node);
if(!node){ return ""; }
var cs = "";
if(node.className){
cs = node.className;
}else if(dojo.html.hasAttribute(node, "class")){
cs = dojo.html.getAttribute(node, "class");
}
return dojo.string.trim(cs);
}
/**
* Returns an array of CSS classes currently assigned
* directly to the node in question. Returns an empty array if no classes
* are found;
*/
dojo.html.getClasses = function(node) {
var c = dojo.html.getClass(node);
return (c == "") ? [] : c.split(/\s+/g);
}
/**
* Returns whether or not the specified classname is a portion of the
* class list currently applied to the node. Does not cover cascaded
* styles, only classes directly applied to the node.
*/
dojo.html.hasClass = function(node, classname){
return dojo.lang.inArray(dojo.html.getClasses(node), classname);
}
/**
* Adds the specified class to the beginning of the class list on the
* passed node. This gives the specified class the highest precidence
* when style cascading is calculated for the node. Returns true or
* false; indicating success or failure of the operation, respectively.
*/
dojo.html.prependClass = function(node, classStr){
classStr += " " + dojo.html.getClass(node);
return dojo.html.setClass(node, classStr);
}
/**
* Adds the specified class to the end of the class list on the
* passed &node;. Returns &true; or &false; indicating success or failure.
*/
dojo.html.addClass = function(node, classStr){
if (dojo.html.hasClass(node, classStr)) {
return false;
}
classStr = dojo.string.trim(dojo.html.getClass(node) + " " + classStr);
return dojo.html.setClass(node, classStr);
}
/**
* Clobbers the existing list of classes for the node, replacing it with
* the list given in the 2nd argument. Returns true or false
* indicating success or failure.
*/
dojo.html.setClass = function(node, classStr){
node = dojo.byId(node);
var cs = new String(classStr);
try{
if(typeof node.className == "string"){
node.className = cs;
}else if(node.setAttribute){
node.setAttribute("class", classStr);
node.className = cs;
}else{
return false;
}
}catch(e){
dojo.debug("dojo.html.setClass() failed", e);
}
return true;
}
/**
* Removes the className from the node;. Returns
* true or false indicating success or failure.
*/
dojo.html.removeClass = function(node, classStr, allowPartialMatches){
var classStr = dojo.string.trim(new String(classStr));
try{
var cs = dojo.html.getClasses(node);
var nca = [];
if(allowPartialMatches){
for(var i = 0; i<cs.length; i++){
if(cs[i].indexOf(classStr) == -1){
nca.push(cs[i]);
}
}
}else{
for(var i=0; i<cs.length; i++){
if(cs[i] != classStr){
nca.push(cs[i]);
}
}
}
dojo.html.setClass(node, nca.join(" "));
}catch(e){
dojo.debug("dojo.html.removeClass() failed", e);
}
return true;
}
/**
* Replaces 'oldClass' and adds 'newClass' to node
*/
dojo.html.replaceClass = function(node, newClass, oldClass) {
dojo.html.removeClass(node, oldClass);
dojo.html.addClass(node, newClass);
}
// Enum type for getElementsByClass classMatchType arg:
dojo.html.classMatchType = {
ContainsAll : 0, // all of the classes are part of the node's class (default)
ContainsAny : 1, // any of the classes are part of the node's class
IsOnly : 2 // only all of the classes are part of the node's class
}
/**
* Returns an array of nodes for the given classStr, children of a
* parent, and optionally of a certain nodeType
*/
dojo.html.getElementsByClass = function(classStr, parent, nodeType, classMatchType, useNonXpath){
parent = dojo.byId(parent) || document;
var classes = classStr.split(/\s+/g);
var nodes = [];
if( classMatchType != 1 && classMatchType != 2 ) classMatchType = 0; // make it enum
var reClass = new RegExp("(\\s|^)((" + classes.join(")|(") + "))(\\s|$)");
var candidateNodes = [];
if(!useNonXpath && document.evaluate) { // supports dom 3 xpath
var xpath = "//" + (nodeType || "*") + "[contains(";
if(classMatchType != dojo.html.classMatchType.ContainsAny){
xpath += "concat(' ',@class,' '), ' " +
classes.join(" ') and contains(concat(' ',@class,' '), ' ") +
" ')]";
}else{
xpath += "concat(' ',@class,' '), ' " +
classes.join(" ')) or contains(concat(' ',@class,' '), ' ") +
" ')]";
}
var xpathResult = document.evaluate(xpath, parent, null, XPathResult.ANY_TYPE, null);
var result = xpathResult.iterateNext();
while(result){
try{
candidateNodes.push(result);
result = xpathResult.iterateNext();
}catch(e){ break; }
}
return candidateNodes;
}else{
if(!nodeType){
nodeType = "*";
}
candidateNodes = parent.getElementsByTagName(nodeType);
var node, i = 0;
outer:
while(node = candidateNodes[i++]){
var nodeClasses = dojo.html.getClasses(node);
if(nodeClasses.length == 0){ continue outer; }
var matches = 0;
for(var j = 0; j < nodeClasses.length; j++){
if(reClass.test(nodeClasses[j])){
if(classMatchType == dojo.html.classMatchType.ContainsAny){
nodes.push(node);
continue outer;
}else{
matches++;
}
}else{
if(classMatchType == dojo.html.classMatchType.IsOnly){
continue outer;
}
}
}
if(matches == classes.length){
if( (classMatchType == dojo.html.classMatchType.IsOnly)&&
(matches == nodeClasses.length)){
nodes.push(node);
}else if(classMatchType == dojo.html.classMatchType.ContainsAll){
nodes.push(node);
}
}
}
return nodes;
}
}
dojo.html.getElementsByClassName = dojo.html.getElementsByClass;
/**
* Returns the mouse position relative to the document (not the viewport).
* For example, if you have a document that is 10000px tall,
* but your browser window is only 100px tall,
* if you scroll to the bottom of the document and call this function it
* will return {x: 0, y: 10000}
*/
dojo.html.getCursorPosition = function(e){
e = e || window.event;
var cursor = {x:0, y:0};
if(e.pageX || e.pageY){
cursor.x = e.pageX;
cursor.y = e.pageY;
}else{
var de = document.documentElement;
var db = document.body;
cursor.x = e.clientX + ((de||db)["scrollLeft"]) - ((de||db)["clientLeft"]);
cursor.y = e.clientY + ((de||db)["scrollTop"]) - ((de||db)["clientTop"]);
}
return cursor;
}
dojo.html.overElement = function(element, e){
element = dojo.byId(element);
var mouse = dojo.html.getCursorPosition(e);
with(dojo.html){
var top = getAbsoluteY(element, true);
var bottom = top + getInnerHeight(element);
var left = getAbsoluteX(element, true);
var right = left + getInnerWidth(element);
}
return (mouse.x >= left && mouse.x <= right &&
mouse.y >= top && mouse.y <= bottom);
}
dojo.html.setActiveStyleSheet = function(title){
var i = 0, a, els = document.getElementsByTagName("link");
while (a = els[i++]) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")){
a.disabled = true;
if (a.getAttribute("title") == title) { a.disabled = false; }
}
}
}
dojo.html.getActiveStyleSheet = function(){
var i = 0, a, els = document.getElementsByTagName("link");
while (a = els[i++]) {
if (a.getAttribute("rel").indexOf("style") != -1 &&
a.getAttribute("title") && !a.disabled) { return a.getAttribute("title"); }
}
return null;
}
dojo.html.getPreferredStyleSheet = function(){
var i = 0, a, els = document.getElementsByTagName("link");
while (a = els[i++]) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("rel").indexOf("alt") == -1
&& a.getAttribute("title")) { return a.getAttribute("title"); }
}
return null;
}
dojo.html.body = function(){
// Note: document.body is not defined for a strict xhtml document
return document.body || document.getElementsByTagName("body")[0];
}
/**
* Like dojo.dom.isTag, except case-insensitive
**/
dojo.html.isTag = function(node /* ... */) {
node = dojo.byId(node);
if(node && node.tagName) {
var arr = dojo.lang.map(dojo.lang.toArray(arguments, 1),
function(a) { return String(a).toLowerCase(); });
return arr[ dojo.lang.find(node.tagName.toLowerCase(), arr) ] || "";
}
return "";
}
dojo.html.copyStyle = function(target, source){
// work around for opera which doesn't have cssText, and for IE which fails on setAttribute
if(dojo.lang.isUndefined(source.style.cssText)){
target.setAttribute("style", source.getAttribute("style"));
}else{
target.style.cssText = source.style.cssText;
}
dojo.html.addClass(target, dojo.html.getClass(source));
}
dojo.html._callExtrasDeprecated = function(inFunc, args) {
var module = "dojo.html.extras";
dojo.deprecated("dojo.html." + inFunc, "moved to " + module, "0.4");
dojo["require"](module); // weird syntax to fool list-profile-deps (build)
return dojo.html[inFunc].apply(dojo.html, args);
}
dojo.html.createNodesFromText = function() {
return dojo.html._callExtrasDeprecated('createNodesFromText', arguments);
}
dojo.html.gravity = function() {
return dojo.html._callExtrasDeprecated('gravity', arguments);
}
dojo.html.placeOnScreen = function() {
return dojo.html._callExtrasDeprecated('placeOnScreen', arguments);
}
dojo.html.placeOnScreenPoint = function() {
return dojo.html._callExtrasDeprecated('placeOnScreenPoint', arguments);
}
dojo.html.renderedTextContent = function() {
return dojo.html._callExtrasDeprecated('renderedTextContent', arguments);
}
dojo.html.BackgroundIframe = function() {
return dojo.html._callExtrasDeprecated('BackgroundIframe', arguments);
}

View file

@ -0,0 +1,14 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: ["dojo.html", "dojo.html.extras", "dojo.html.shadow"]
});
dojo.provide("dojo.html.*");

View file

@ -0,0 +1,428 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.html");
dojo.provide("dojo.html.extras");
dojo.require("dojo.string.extras");
/**
* Calculates the mouse's direction of gravity relative to the centre
* of the given node.
* <p>
* If you wanted to insert a node into a DOM tree based on the mouse
* position you might use the following code:
* <pre>
* if (gravity(node, e) & gravity.NORTH) { [insert before]; }
* else { [insert after]; }
* </pre>
*
* @param node The node
* @param e The event containing the mouse coordinates
* @return The directions, NORTH or SOUTH and EAST or WEST. These
* are properties of the function.
*/
dojo.html.gravity = function(node, e){
node = dojo.byId(node);
var mouse = dojo.html.getCursorPosition(e);
with (dojo.html) {
var nodecenterx = getAbsoluteX(node, true) + (getInnerWidth(node) / 2);
var nodecentery = getAbsoluteY(node, true) + (getInnerHeight(node) / 2);
}
with (dojo.html.gravity) {
return ((mouse.x < nodecenterx ? WEST : EAST) |
(mouse.y < nodecentery ? NORTH : SOUTH));
}
}
dojo.html.gravity.NORTH = 1;
dojo.html.gravity.SOUTH = 1 << 1;
dojo.html.gravity.EAST = 1 << 2;
dojo.html.gravity.WEST = 1 << 3;
/**
* Attempts to return the text as it would be rendered, with the line breaks
* sorted out nicely. Unfinished.
*/
dojo.html.renderedTextContent = function(node){
node = dojo.byId(node);
var result = "";
if (node == null) { return result; }
for (var i = 0; i < node.childNodes.length; i++) {
switch (node.childNodes[i].nodeType) {
case 1: // ELEMENT_NODE
case 5: // ENTITY_REFERENCE_NODE
var display = "unknown";
try {
display = dojo.style.getStyle(node.childNodes[i], "display");
} catch(E) {}
switch (display) {
case "block": case "list-item": case "run-in":
case "table": case "table-row-group": case "table-header-group":
case "table-footer-group": case "table-row": case "table-column-group":
case "table-column": case "table-cell": case "table-caption":
// TODO: this shouldn't insert double spaces on aligning blocks
result += "\n";
result += dojo.html.renderedTextContent(node.childNodes[i]);
result += "\n";
break;
case "none": break;
default:
if(node.childNodes[i].tagName && node.childNodes[i].tagName.toLowerCase() == "br") {
result += "\n";
} else {
result += dojo.html.renderedTextContent(node.childNodes[i]);
}
break;
}
break;
case 3: // TEXT_NODE
case 2: // ATTRIBUTE_NODE
case 4: // CDATA_SECTION_NODE
var text = node.childNodes[i].nodeValue;
var textTransform = "unknown";
try {
textTransform = dojo.style.getStyle(node, "text-transform");
} catch(E) {}
switch (textTransform){
case "capitalize": text = dojo.string.capitalize(text); break;
case "uppercase": text = text.toUpperCase(); break;
case "lowercase": text = text.toLowerCase(); break;
default: break; // leave as is
}
// TODO: implement
switch (textTransform){
case "nowrap": break;
case "pre-wrap": break;
case "pre-line": break;
case "pre": break; // leave as is
default:
// remove whitespace and collapse first space
text = text.replace(/\s+/, " ");
if (/\s$/.test(result)) { text.replace(/^\s/, ""); }
break;
}
result += text;
break;
default:
break;
}
}
return result;
}
dojo.html.createNodesFromText = function(txt, trim){
if(trim) { txt = dojo.string.trim(txt); }
var tn = document.createElement("div");
// tn.style.display = "none";
tn.style.visibility= "hidden";
document.body.appendChild(tn);
var tableType = "none";
if((/^<t[dh][\s\r\n>]/i).test(dojo.string.trimStart(txt))) {
txt = "<table><tbody><tr>" + txt + "</tr></tbody></table>";
tableType = "cell";
} else if((/^<tr[\s\r\n>]/i).test(dojo.string.trimStart(txt))) {
txt = "<table><tbody>" + txt + "</tbody></table>";
tableType = "row";
} else if((/^<(thead|tbody|tfoot)[\s\r\n>]/i).test(dojo.string.trimStart(txt))) {
txt = "<table>" + txt + "</table>";
tableType = "section";
}
tn.innerHTML = txt;
if(tn["normalize"]){
tn.normalize();
}
var parent = null;
switch(tableType) {
case "cell":
parent = tn.getElementsByTagName("tr")[0];
break;
case "row":
parent = tn.getElementsByTagName("tbody")[0];
break;
case "section":
parent = tn.getElementsByTagName("table")[0];
break;
default:
parent = tn;
break;
}
/* this doesn't make much sense, I'm assuming it just meant trim() so wrap was replaced with trim
if(wrap){
var ret = [];
// start hack
var fc = tn.firstChild;
ret[0] = ((fc.nodeValue == " ")||(fc.nodeValue == "\t")) ? fc.nextSibling : fc;
// end hack
// tn.style.display = "none";
document.body.removeChild(tn);
return ret;
}
*/
var nodes = [];
for(var x=0; x<parent.childNodes.length; x++){
nodes.push(parent.childNodes[x].cloneNode(true));
}
tn.style.display = "none"; // FIXME: why do we do this?
document.body.removeChild(tn);
return nodes;
}
/* TODO: merge placeOnScreen and placeOnScreenPoint to make 1 function that allows you
* to define which corner(s) you want to bind to. Something like so:
*
* kes(node, desiredX, desiredY, "TR")
* kes(node, [desiredX, desiredY], ["TR", "BL"])
*
* TODO: make this function have variable call sigs
*
* kes(node, ptArray, cornerArray, padding, hasScroll)
* kes(node, ptX, ptY, cornerA, cornerB, cornerC, paddingArray, hasScroll)
*/
/**
* Keeps 'node' in the visible area of the screen while trying to
* place closest to desiredX, desiredY. The input coordinates are
* expected to be the desired screen position, not accounting for
* scrolling. If you already accounted for scrolling, set 'hasScroll'
* to true. Set padding to either a number or array for [paddingX, paddingY]
* to put some buffer around the element you want to position.
* NOTE: node is assumed to be absolutely or relatively positioned.
*
* Alternate call sig:
* placeOnScreen(node, [x, y], padding, hasScroll)
*
* Examples:
* placeOnScreen(node, 100, 200)
* placeOnScreen("myId", [800, 623], 5)
* placeOnScreen(node, 234, 3284, [2, 5], true)
*/
dojo.html.placeOnScreen = function(node, desiredX, desiredY, padding, hasScroll) {
if(dojo.lang.isArray(desiredX)) {
hasScroll = padding;
padding = desiredY;
desiredY = desiredX[1];
desiredX = desiredX[0];
}
if(!isNaN(padding)) {
padding = [Number(padding), Number(padding)];
} else if(!dojo.lang.isArray(padding)) {
padding = [0, 0];
}
var scroll = dojo.html.getScrollOffset();
var view = dojo.html.getViewportSize();
node = dojo.byId(node);
var w = node.offsetWidth + padding[0];
var h = node.offsetHeight + padding[1];
if(hasScroll) {
desiredX -= scroll.x;
desiredY -= scroll.y;
}
var x = desiredX + w;
if(x > view.w) {
x = view.w - w;
} else {
x = desiredX;
}
x = Math.max(padding[0], x) + scroll.x;
var y = desiredY + h;
if(y > view.h) {
y = view.h - h;
} else {
y = desiredY;
}
y = Math.max(padding[1], y) + scroll.y;
node.style.left = x + "px";
node.style.top = y + "px";
var ret = [x, y];
ret.x = x;
ret.y = y;
return ret;
}
/**
* Like placeOnScreenPoint except that it attempts to keep one of the node's
* corners at desiredX, desiredY. Favors the bottom right position
*
* Examples placing node at mouse position (where e = [Mouse event]):
* placeOnScreenPoint(node, e.clientX, e.clientY);
*/
dojo.html.placeOnScreenPoint = function(node, desiredX, desiredY, padding, hasScroll) {
if(dojo.lang.isArray(desiredX)) {
hasScroll = padding;
padding = desiredY;
desiredY = desiredX[1];
desiredX = desiredX[0];
}
if(!isNaN(padding)) {
padding = [Number(padding), Number(padding)];
} else if(!dojo.lang.isArray(padding)) {
padding = [0, 0];
}
var scroll = dojo.html.getScrollOffset();
var view = dojo.html.getViewportSize();
node = dojo.byId(node);
var oldDisplay = node.style.display;
node.style.display="";
var w = dojo.style.getInnerWidth(node);
var h = dojo.style.getInnerHeight(node);
node.style.display=oldDisplay;
if(hasScroll) {
desiredX -= scroll.x;
desiredY -= scroll.y;
}
var x = -1, y = -1;
//dojo.debug((desiredX+padding[0]) + w, "<=", view.w, "&&", (desiredY+padding[1]) + h, "<=", view.h);
if((desiredX+padding[0]) + w <= view.w && (desiredY+padding[1]) + h <= view.h) { // TL
x = (desiredX+padding[0]);
y = (desiredY+padding[1]);
//dojo.debug("TL", x, y);
}
//dojo.debug((desiredX-padding[0]), "<=", view.w, "&&", (desiredY+padding[1]) + h, "<=", view.h);
if((x < 0 || y < 0) && (desiredX-padding[0]) <= view.w && (desiredY+padding[1]) + h <= view.h) { // TR
x = (desiredX-padding[0]) - w;
y = (desiredY+padding[1]);
//dojo.debug("TR", x, y);
}
//dojo.debug((desiredX+padding[0]) + w, "<=", view.w, "&&", (desiredY-padding[1]), "<=", view.h);
if((x < 0 || y < 0) && (desiredX+padding[0]) + w <= view.w && (desiredY-padding[1]) <= view.h) { // BL
x = (desiredX+padding[0]);
y = (desiredY-padding[1]) - h;
//dojo.debug("BL", x, y);
}
//dojo.debug((desiredX-padding[0]), "<=", view.w, "&&", (desiredY-padding[1]), "<=", view.h);
if((x < 0 || y < 0) && (desiredX-padding[0]) <= view.w && (desiredY-padding[1]) <= view.h) { // BR
x = (desiredX-padding[0]) - w;
y = (desiredY-padding[1]) - h;
//dojo.debug("BR", x, y);
}
if(x < 0 || y < 0 || (x + w > view.w) || (y + h > view.h)) {
return dojo.html.placeOnScreen(node, desiredX, desiredY, padding, hasScroll);
}
x += scroll.x;
y += scroll.y;
node.style.left = x + "px";
node.style.top = y + "px";
var ret = [x, y];
ret.x = x;
ret.y = y;
return ret;
}
/**
* For IE z-index schenanigans
* Two possible uses:
* 1. new dojo.html.BackgroundIframe(node)
* Makes a background iframe as a child of node, that fills area (and position) of node
*
* 2. new dojo.html.BackgroundIframe()
* Attaches frame to document.body. User must call size() to set size.
*/
dojo.html.BackgroundIframe = function(node) {
if(dojo.render.html.ie55 || dojo.render.html.ie60) {
var html=
"<iframe "
+"style='position: absolute; left: 0px; top: 0px; width: 100%; height: 100%;"
+ "z-index: -1; filter:Alpha(Opacity=\"0\");' "
+">";
this.iframe = document.createElement(html);
if(node){
node.appendChild(this.iframe);
this.domNode=node;
}else{
document.body.appendChild(this.iframe);
this.iframe.style.display="none";
}
}
}
dojo.lang.extend(dojo.html.BackgroundIframe, {
iframe: null,
// TODO: this function shouldn't be necessary but setting width=height=100% doesn't work!
onResized: function(){
if(this.iframe && this.domNode && this.domNode.parentElement){ // No parentElement if onResized() timeout event occurs on a removed domnode
var w = dojo.style.getOuterWidth(this.domNode);
var h = dojo.style.getOuterHeight(this.domNode);
if (w == 0 || h == 0 ){
dojo.lang.setTimeout(this, this.onResized, 50);
return;
}
var s = this.iframe.style;
s.width = w + "px";
s.height = h + "px";
}
},
// Call this function if the iframe is connected to document.body rather
// than the node being shadowed (TODO: erase)
size: function(node) {
if(!this.iframe) { return; }
var coords = dojo.style.toCoordinateArray(node, true);
var s = this.iframe.style;
s.width = coords.w + "px";
s.height = coords.h + "px";
s.left = coords.x + "px";
s.top = coords.y + "px";
},
setZIndex: function(node /* or number */) {
if(!this.iframe) { return; }
if(dojo.dom.isNode(node)) {
this.iframe.style.zIndex = dojo.html.getStyle(node, "z-index") - 1;
} else if(!isNaN(node)) {
this.iframe.style.zIndex = node;
}
},
show: function() {
if(!this.iframe) { return; }
this.iframe.style.display = "block";
},
hide: function() {
if(!this.ie) { return; }
var s = this.iframe.style;
s.display = "none";
},
remove: function() {
dojo.dom.removeNode(this.iframe);
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Some files were not shown because too many files have changed in this diff Show more