зеркало из https://github.com/mozilla/gecko-dev.git
Bug 379506 - Integrate MochiKit Test Suite, patch by John Resig <jresig@mozilla.com>
This commit is contained in:
Родитель
40dfe5d57d
Коммит
b9231f4081
|
@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk
|
|||
DIRS = lib \
|
||||
prototype \
|
||||
offline \
|
||||
mochikit \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,59 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/ajax/mochikit
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = \
|
||||
Mochikit \
|
||||
tests \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
test_Mochikit.html \
|
||||
manifest.json \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
|
@ -0,0 +1,699 @@
|
|||
/***
|
||||
|
||||
MochiKit.Async 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide("MochiKit.Async");
|
||||
dojo.require("MochiKit.Base");
|
||||
}
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Async depends on MochiKit.Base!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Async) == 'undefined') {
|
||||
MochiKit.Async = {};
|
||||
}
|
||||
|
||||
MochiKit.Async.NAME = "MochiKit.Async";
|
||||
MochiKit.Async.VERSION = "1.4";
|
||||
MochiKit.Async.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
MochiKit.Async.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
/** @id MochiKit.Async.Deferred */
|
||||
MochiKit.Async.Deferred = function (/* optional */ canceller) {
|
||||
this.chain = [];
|
||||
this.id = this._nextId();
|
||||
this.fired = -1;
|
||||
this.paused = 0;
|
||||
this.results = [null, null];
|
||||
this.canceller = canceller;
|
||||
this.silentlyCancelled = false;
|
||||
this.chained = false;
|
||||
};
|
||||
|
||||
MochiKit.Async.Deferred.prototype = {
|
||||
/** @id MochiKit.Async.Deferred.prototype.repr */
|
||||
repr: function () {
|
||||
var state;
|
||||
if (this.fired == -1) {
|
||||
state = 'unfired';
|
||||
} else if (this.fired === 0) {
|
||||
state = 'success';
|
||||
} else {
|
||||
state = 'error';
|
||||
}
|
||||
return 'Deferred(' + this.id + ', ' + state + ')';
|
||||
},
|
||||
|
||||
toString: MochiKit.Base.forwardCall("repr"),
|
||||
|
||||
_nextId: MochiKit.Base.counter(),
|
||||
|
||||
/** @id MochiKit.Async.Deferred.prototype.cancel */
|
||||
cancel: function () {
|
||||
var self = MochiKit.Async;
|
||||
if (this.fired == -1) {
|
||||
if (this.canceller) {
|
||||
this.canceller(this);
|
||||
} else {
|
||||
this.silentlyCancelled = true;
|
||||
}
|
||||
if (this.fired == -1) {
|
||||
this.errback(new self.CancelledError(this));
|
||||
}
|
||||
} else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) {
|
||||
this.results[0].cancel();
|
||||
}
|
||||
},
|
||||
|
||||
_resback: function (res) {
|
||||
/***
|
||||
|
||||
The primitive that means either callback or errback
|
||||
|
||||
***/
|
||||
this.fired = ((res instanceof Error) ? 1 : 0);
|
||||
this.results[this.fired] = res;
|
||||
this._fire();
|
||||
},
|
||||
|
||||
_check: function () {
|
||||
if (this.fired != -1) {
|
||||
if (!this.silentlyCancelled) {
|
||||
throw new MochiKit.Async.AlreadyCalledError(this);
|
||||
}
|
||||
this.silentlyCancelled = false;
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.Deferred.prototype.callback */
|
||||
callback: function (res) {
|
||||
this._check();
|
||||
if (res instanceof MochiKit.Async.Deferred) {
|
||||
throw new Error("Deferred instances can only be chained if they are the result of a callback");
|
||||
}
|
||||
this._resback(res);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.Deferred.prototype.errback */
|
||||
errback: function (res) {
|
||||
this._check();
|
||||
var self = MochiKit.Async;
|
||||
if (res instanceof self.Deferred) {
|
||||
throw new Error("Deferred instances can only be chained if they are the result of a callback");
|
||||
}
|
||||
if (!(res instanceof Error)) {
|
||||
res = new self.GenericError(res);
|
||||
}
|
||||
this._resback(res);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.Deferred.prototype.addBoth */
|
||||
addBoth: function (fn) {
|
||||
if (arguments.length > 1) {
|
||||
fn = MochiKit.Base.partial.apply(null, arguments);
|
||||
}
|
||||
return this.addCallbacks(fn, fn);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.Deferred.prototype.addCallback */
|
||||
addCallback: function (fn) {
|
||||
if (arguments.length > 1) {
|
||||
fn = MochiKit.Base.partial.apply(null, arguments);
|
||||
}
|
||||
return this.addCallbacks(fn, null);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.Deferred.prototype.addErrback */
|
||||
addErrback: function (fn) {
|
||||
if (arguments.length > 1) {
|
||||
fn = MochiKit.Base.partial.apply(null, arguments);
|
||||
}
|
||||
return this.addCallbacks(null, fn);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.Deferred.prototype.addCallbacks */
|
||||
addCallbacks: function (cb, eb) {
|
||||
if (this.chained) {
|
||||
throw new Error("Chained Deferreds can not be re-used");
|
||||
}
|
||||
this.chain.push([cb, eb]);
|
||||
if (this.fired >= 0) {
|
||||
this._fire();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
_fire: function () {
|
||||
/***
|
||||
|
||||
Used internally to exhaust the callback sequence when a result
|
||||
is available.
|
||||
|
||||
***/
|
||||
var chain = this.chain;
|
||||
var fired = this.fired;
|
||||
var res = this.results[fired];
|
||||
var self = this;
|
||||
var cb = null;
|
||||
while (chain.length > 0 && this.paused === 0) {
|
||||
// Array
|
||||
var pair = chain.shift();
|
||||
var f = pair[fired];
|
||||
if (f === null) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
res = f(res);
|
||||
fired = ((res instanceof Error) ? 1 : 0);
|
||||
if (res instanceof MochiKit.Async.Deferred) {
|
||||
cb = function (res) {
|
||||
self._resback(res);
|
||||
self.paused--;
|
||||
if ((self.paused === 0) && (self.fired >= 0)) {
|
||||
self._fire();
|
||||
}
|
||||
};
|
||||
this.paused++;
|
||||
}
|
||||
} catch (err) {
|
||||
fired = 1;
|
||||
if (!(err instanceof Error)) {
|
||||
err = new MochiKit.Async.GenericError(err);
|
||||
}
|
||||
res = err;
|
||||
}
|
||||
}
|
||||
this.fired = fired;
|
||||
this.results[fired] = res;
|
||||
if (cb && this.paused) {
|
||||
// this is for "tail recursion" in case the dependent deferred
|
||||
// is already fired
|
||||
res.addBoth(cb);
|
||||
res.chained = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.Base.update(MochiKit.Async, {
|
||||
/** @id MochiKit.Async.evalJSONRequest */
|
||||
evalJSONRequest: function (req) {
|
||||
return MochiKit.Base.evalJSON(req.responseText);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.succeed */
|
||||
succeed: function (/* optional */result) {
|
||||
var d = new MochiKit.Async.Deferred();
|
||||
d.callback.apply(d, arguments);
|
||||
return d;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.fail */
|
||||
fail: function (/* optional */result) {
|
||||
var d = new MochiKit.Async.Deferred();
|
||||
d.errback.apply(d, arguments);
|
||||
return d;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.getXMLHttpRequest */
|
||||
getXMLHttpRequest: function () {
|
||||
var self = arguments.callee;
|
||||
if (!self.XMLHttpRequest) {
|
||||
var tryThese = [
|
||||
function () { return new XMLHttpRequest(); },
|
||||
function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
|
||||
function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
|
||||
function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
|
||||
function () {
|
||||
throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
|
||||
}
|
||||
];
|
||||
for (var i = 0; i < tryThese.length; i++) {
|
||||
var func = tryThese[i];
|
||||
try {
|
||||
self.XMLHttpRequest = func;
|
||||
return func();
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
return self.XMLHttpRequest();
|
||||
},
|
||||
|
||||
_xhr_onreadystatechange: function (d) {
|
||||
// MochiKit.Logging.logDebug('this.readyState', this.readyState);
|
||||
var m = MochiKit.Base;
|
||||
if (this.readyState == 4) {
|
||||
// IE SUCKS
|
||||
try {
|
||||
this.onreadystatechange = null;
|
||||
} catch (e) {
|
||||
try {
|
||||
this.onreadystatechange = m.noop;
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
var status = null;
|
||||
try {
|
||||
status = this.status;
|
||||
if (!status && m.isNotEmpty(this.responseText)) {
|
||||
// 0 or undefined seems to mean cached or local
|
||||
status = 304;
|
||||
}
|
||||
} catch (e) {
|
||||
// pass
|
||||
// MochiKit.Logging.logDebug('error getting status?', repr(items(e)));
|
||||
}
|
||||
// 200 is OK, 201 is CREATED, 204 is NO CONTENT
|
||||
// 304 is NOT MODIFIED, 1223 is apparently a bug in IE
|
||||
if (status == 200 || status == 201 || status == 204 ||
|
||||
status == 304 || status == 1223) {
|
||||
d.callback(this);
|
||||
} else {
|
||||
var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed");
|
||||
if (err.number) {
|
||||
// XXX: This seems to happen on page change
|
||||
d.errback(err);
|
||||
} else {
|
||||
// XXX: this seems to happen when the server is unreachable
|
||||
d.errback(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_xhr_canceller: function (req) {
|
||||
// IE SUCKS
|
||||
try {
|
||||
req.onreadystatechange = null;
|
||||
} catch (e) {
|
||||
try {
|
||||
req.onreadystatechange = MochiKit.Base.noop;
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
req.abort();
|
||||
},
|
||||
|
||||
|
||||
/** @id MochiKit.Async.sendXMLHttpRequest */
|
||||
sendXMLHttpRequest: function (req, /* optional */ sendContent) {
|
||||
if (typeof(sendContent) == "undefined" || sendContent === null) {
|
||||
sendContent = "";
|
||||
}
|
||||
|
||||
var m = MochiKit.Base;
|
||||
var self = MochiKit.Async;
|
||||
var d = new self.Deferred(m.partial(self._xhr_canceller, req));
|
||||
|
||||
try {
|
||||
req.onreadystatechange = m.bind(self._xhr_onreadystatechange,
|
||||
req, d);
|
||||
req.send(sendContent);
|
||||
} catch (e) {
|
||||
try {
|
||||
req.onreadystatechange = null;
|
||||
} catch (ignore) {
|
||||
// pass
|
||||
}
|
||||
d.errback(e);
|
||||
}
|
||||
|
||||
return d;
|
||||
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.doXHR */
|
||||
doXHR: function (url, opts) {
|
||||
/*
|
||||
Work around a Firefox bug by dealing with XHR during
|
||||
the next event loop iteration. Maybe it's this one:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=249843
|
||||
*/
|
||||
var self = MochiKit.Async;
|
||||
return self.callLater(0, self._doXHR, url, opts);
|
||||
},
|
||||
|
||||
_doXHR: function (url, opts) {
|
||||
var m = MochiKit.Base;
|
||||
opts = m.update({
|
||||
method: 'GET',
|
||||
sendContent: ''
|
||||
/*
|
||||
queryString: undefined,
|
||||
username: undefined,
|
||||
password: undefined,
|
||||
headers: undefined,
|
||||
mimeType: undefined
|
||||
*/
|
||||
}, opts);
|
||||
var self = MochiKit.Async;
|
||||
var req = self.getXMLHttpRequest();
|
||||
if (opts.queryString) {
|
||||
var qs = m.queryString(opts.queryString);
|
||||
if (qs) {
|
||||
url += "?" + qs;
|
||||
}
|
||||
}
|
||||
// Safari will send undefined:undefined, so we have to check.
|
||||
// We can't use apply, since the function is native.
|
||||
if ('username' in opts) {
|
||||
req.open(opts.method, url, true, opts.username, opts.password);
|
||||
} else {
|
||||
req.open(opts.method, url, true);
|
||||
}
|
||||
if (req.overrideMimeType && opts.mimeType) {
|
||||
req.overrideMimeType(opts.mimeType);
|
||||
}
|
||||
if (opts.headers) {
|
||||
var headers = opts.headers;
|
||||
if (!m.isArrayLike(headers)) {
|
||||
headers = m.items(headers);
|
||||
}
|
||||
for (var i = 0; i < headers.length; i++) {
|
||||
var header = headers[i];
|
||||
var name = header[0];
|
||||
var value = header[1];
|
||||
req.setRequestHeader(name, value);
|
||||
}
|
||||
}
|
||||
return self.sendXMLHttpRequest(req, opts.sendContent);
|
||||
},
|
||||
|
||||
_buildURL: function (url/*, ...*/) {
|
||||
if (arguments.length > 1) {
|
||||
var m = MochiKit.Base;
|
||||
var qs = m.queryString.apply(null, m.extend(null, arguments, 1));
|
||||
if (qs) {
|
||||
return url + "?" + qs;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.doSimpleXMLHttpRequest */
|
||||
doSimpleXMLHttpRequest: function (url/*, ...*/) {
|
||||
var self = MochiKit.Async;
|
||||
url = self._buildURL.apply(self, arguments);
|
||||
return self.doXHR(url);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.loadJSONDoc */
|
||||
loadJSONDoc: function (url/*, ...*/) {
|
||||
var self = MochiKit.Async;
|
||||
url = self._buildURL.apply(self, arguments);
|
||||
var d = self.doXHR(url, {
|
||||
'mimeType': 'text/plain',
|
||||
'headers': [['Accept', 'application/json']]
|
||||
});
|
||||
d = d.addCallback(self.evalJSONRequest);
|
||||
return d;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.wait */
|
||||
wait: function (seconds, /* optional */value) {
|
||||
var d = new MochiKit.Async.Deferred();
|
||||
var m = MochiKit.Base;
|
||||
if (typeof(value) != 'undefined') {
|
||||
d.addCallback(function () { return value; });
|
||||
}
|
||||
var timeout = setTimeout(
|
||||
m.bind("callback", d),
|
||||
Math.floor(seconds * 1000));
|
||||
d.canceller = function () {
|
||||
try {
|
||||
clearTimeout(timeout);
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
};
|
||||
return d;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Async.callLater */
|
||||
callLater: function (seconds, func) {
|
||||
var m = MochiKit.Base;
|
||||
var pfunc = m.partial.apply(m, m.extend(null, arguments, 1));
|
||||
return MochiKit.Async.wait(seconds).addCallback(
|
||||
function (res) { return pfunc(); }
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/** @id MochiKit.Async.DeferredLock */
|
||||
MochiKit.Async.DeferredLock = function () {
|
||||
this.waiting = [];
|
||||
this.locked = false;
|
||||
this.id = this._nextId();
|
||||
};
|
||||
|
||||
MochiKit.Async.DeferredLock.prototype = {
|
||||
__class__: MochiKit.Async.DeferredLock,
|
||||
/** @id MochiKit.Async.DeferredLock.prototype.acquire */
|
||||
acquire: function () {
|
||||
var d = new MochiKit.Async.Deferred();
|
||||
if (this.locked) {
|
||||
this.waiting.push(d);
|
||||
} else {
|
||||
this.locked = true;
|
||||
d.callback(this);
|
||||
}
|
||||
return d;
|
||||
},
|
||||
/** @id MochiKit.Async.DeferredLock.prototype.release */
|
||||
release: function () {
|
||||
if (!this.locked) {
|
||||
throw TypeError("Tried to release an unlocked DeferredLock");
|
||||
}
|
||||
this.locked = false;
|
||||
if (this.waiting.length > 0) {
|
||||
this.locked = true;
|
||||
this.waiting.shift().callback(this);
|
||||
}
|
||||
},
|
||||
_nextId: MochiKit.Base.counter(),
|
||||
repr: function () {
|
||||
var state;
|
||||
if (this.locked) {
|
||||
state = 'locked, ' + this.waiting.length + ' waiting';
|
||||
} else {
|
||||
state = 'unlocked';
|
||||
}
|
||||
return 'DeferredLock(' + this.id + ', ' + state + ')';
|
||||
},
|
||||
toString: MochiKit.Base.forwardCall("repr")
|
||||
|
||||
};
|
||||
|
||||
/** @id MochiKit.Async.DeferredList */
|
||||
MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller) {
|
||||
|
||||
// call parent constructor
|
||||
MochiKit.Async.Deferred.apply(this, [canceller]);
|
||||
|
||||
this.list = list;
|
||||
var resultList = [];
|
||||
this.resultList = resultList;
|
||||
|
||||
this.finishedCount = 0;
|
||||
this.fireOnOneCallback = fireOnOneCallback;
|
||||
this.fireOnOneErrback = fireOnOneErrback;
|
||||
this.consumeErrors = consumeErrors;
|
||||
|
||||
var cb = MochiKit.Base.bind(this._cbDeferred, this);
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var d = list[i];
|
||||
resultList.push(undefined);
|
||||
d.addCallback(cb, i, true);
|
||||
d.addErrback(cb, i, false);
|
||||
}
|
||||
|
||||
if (list.length === 0 && !fireOnOneCallback) {
|
||||
this.callback(this.resultList);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred();
|
||||
|
||||
MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) {
|
||||
this.resultList[index] = [succeeded, result];
|
||||
this.finishedCount += 1;
|
||||
if (this.fired == -1) {
|
||||
if (succeeded && this.fireOnOneCallback) {
|
||||
this.callback([index, result]);
|
||||
} else if (!succeeded && this.fireOnOneErrback) {
|
||||
this.errback(result);
|
||||
} else if (this.finishedCount == this.list.length) {
|
||||
this.callback(this.resultList);
|
||||
}
|
||||
}
|
||||
if (!succeeded && this.consumeErrors) {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/** @id MochiKit.Async.gatherResults */
|
||||
MochiKit.Async.gatherResults = function (deferredList) {
|
||||
var d = new MochiKit.Async.DeferredList(deferredList, false, true, false);
|
||||
d.addCallback(function (results) {
|
||||
var ret = [];
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
ret.push(results[i][1]);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
return d;
|
||||
};
|
||||
|
||||
/** @id MochiKit.Async.maybeDeferred */
|
||||
MochiKit.Async.maybeDeferred = function (func) {
|
||||
var self = MochiKit.Async;
|
||||
var result;
|
||||
try {
|
||||
var r = func.apply(null, MochiKit.Base.extend([], arguments, 1));
|
||||
if (r instanceof self.Deferred) {
|
||||
result = r;
|
||||
} else if (r instanceof Error) {
|
||||
result = self.fail(r);
|
||||
} else {
|
||||
result = self.succeed(r);
|
||||
}
|
||||
} catch (e) {
|
||||
result = self.fail(e);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
MochiKit.Async.EXPORT = [
|
||||
"AlreadyCalledError",
|
||||
"CancelledError",
|
||||
"BrowserComplianceError",
|
||||
"GenericError",
|
||||
"XMLHttpRequestError",
|
||||
"Deferred",
|
||||
"succeed",
|
||||
"fail",
|
||||
"getXMLHttpRequest",
|
||||
"doSimpleXMLHttpRequest",
|
||||
"loadJSONDoc",
|
||||
"wait",
|
||||
"callLater",
|
||||
"sendXMLHttpRequest",
|
||||
"DeferredLock",
|
||||
"DeferredList",
|
||||
"gatherResults",
|
||||
"maybeDeferred",
|
||||
"doXHR"
|
||||
];
|
||||
|
||||
MochiKit.Async.EXPORT_OK = [
|
||||
"evalJSONRequest"
|
||||
];
|
||||
|
||||
MochiKit.Async.__new__ = function () {
|
||||
var m = MochiKit.Base;
|
||||
var ne = m.partial(m._newNamedError, this);
|
||||
|
||||
ne("AlreadyCalledError",
|
||||
/** @id MochiKit.Async.AlreadyCalledError */
|
||||
function (deferred) {
|
||||
/***
|
||||
|
||||
Raised by the Deferred if callback or errback happens
|
||||
after it was already fired.
|
||||
|
||||
***/
|
||||
this.deferred = deferred;
|
||||
}
|
||||
);
|
||||
|
||||
ne("CancelledError",
|
||||
/** @id MochiKit.Async.CancelledError */
|
||||
function (deferred) {
|
||||
/***
|
||||
|
||||
Raised by the Deferred cancellation mechanism.
|
||||
|
||||
***/
|
||||
this.deferred = deferred;
|
||||
}
|
||||
);
|
||||
|
||||
ne("BrowserComplianceError",
|
||||
/** @id MochiKit.Async.BrowserComplianceError */
|
||||
function (msg) {
|
||||
/***
|
||||
|
||||
Raised when the JavaScript runtime is not capable of performing
|
||||
the given function. Technically, this should really never be
|
||||
raised because a non-conforming JavaScript runtime probably
|
||||
isn't going to support exceptions in the first place.
|
||||
|
||||
***/
|
||||
this.message = msg;
|
||||
}
|
||||
);
|
||||
|
||||
ne("GenericError",
|
||||
/** @id MochiKit.Async.GenericError */
|
||||
function (msg) {
|
||||
this.message = msg;
|
||||
}
|
||||
);
|
||||
|
||||
ne("XMLHttpRequestError",
|
||||
/** @id MochiKit.Async.XMLHttpRequestError */
|
||||
function (req, msg) {
|
||||
/***
|
||||
|
||||
Raised when an XMLHttpRequest does not complete for any reason.
|
||||
|
||||
***/
|
||||
this.req = req;
|
||||
this.message = msg;
|
||||
try {
|
||||
// Strange but true that this can raise in some cases.
|
||||
this.number = req.status;
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
|
||||
};
|
||||
|
||||
MochiKit.Async.__new__();
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Async);
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,902 @@
|
|||
/***
|
||||
|
||||
MochiKit.Color 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito and others. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Color');
|
||||
dojo.require('MochiKit.Base');
|
||||
dojo.require('MochiKit.DOM');
|
||||
dojo.require('MochiKit.Style');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
JSAN.use("MochiKit.DOM", []);
|
||||
JSAN.use("MochiKit.Style", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Color depends on MochiKit.Base";
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.DOM) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Color depends on MochiKit.DOM";
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Style) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Color depends on MochiKit.Style";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Color) == "undefined") {
|
||||
MochiKit.Color = {};
|
||||
}
|
||||
|
||||
MochiKit.Color.NAME = "MochiKit.Color";
|
||||
MochiKit.Color.VERSION = "1.4";
|
||||
|
||||
MochiKit.Color.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
|
||||
MochiKit.Color.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
|
||||
/** @id MochiKit.Color.Color */
|
||||
MochiKit.Color.Color = function (red, green, blue, alpha) {
|
||||
if (typeof(alpha) == 'undefined' || alpha === null) {
|
||||
alpha = 1.0;
|
||||
}
|
||||
this.rgb = {
|
||||
r: red,
|
||||
g: green,
|
||||
b: blue,
|
||||
a: alpha
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Prototype methods
|
||||
|
||||
MochiKit.Color.Color.prototype = {
|
||||
|
||||
__class__: MochiKit.Color.Color,
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.colorWithAlpha */
|
||||
colorWithAlpha: function (alpha) {
|
||||
var rgb = this.rgb;
|
||||
var m = MochiKit.Color;
|
||||
return m.Color.fromRGB(rgb.r, rgb.g, rgb.b, alpha);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.colorWithHue */
|
||||
colorWithHue: function (hue) {
|
||||
// get an HSL model, and set the new hue...
|
||||
var hsl = this.asHSL();
|
||||
hsl.h = hue;
|
||||
var m = MochiKit.Color;
|
||||
// convert back to RGB...
|
||||
return m.Color.fromHSL(hsl);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.colorWithSaturation */
|
||||
colorWithSaturation: function (saturation) {
|
||||
// get an HSL model, and set the new hue...
|
||||
var hsl = this.asHSL();
|
||||
hsl.s = saturation;
|
||||
var m = MochiKit.Color;
|
||||
// convert back to RGB...
|
||||
return m.Color.fromHSL(hsl);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.colorWithLightness */
|
||||
colorWithLightness: function (lightness) {
|
||||
// get an HSL model, and set the new hue...
|
||||
var hsl = this.asHSL();
|
||||
hsl.l = lightness;
|
||||
var m = MochiKit.Color;
|
||||
// convert back to RGB...
|
||||
return m.Color.fromHSL(hsl);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.darkerColorWithLevel */
|
||||
darkerColorWithLevel: function (level) {
|
||||
var hsl = this.asHSL();
|
||||
hsl.l = Math.max(hsl.l - level, 0);
|
||||
var m = MochiKit.Color;
|
||||
return m.Color.fromHSL(hsl);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.lighterColorWithLevel */
|
||||
lighterColorWithLevel: function (level) {
|
||||
var hsl = this.asHSL();
|
||||
hsl.l = Math.min(hsl.l + level, 1);
|
||||
var m = MochiKit.Color;
|
||||
return m.Color.fromHSL(hsl);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.blendedColor */
|
||||
blendedColor: function (other, /* optional */ fraction) {
|
||||
if (typeof(fraction) == 'undefined' || fraction === null) {
|
||||
fraction = 0.5;
|
||||
}
|
||||
var sf = 1.0 - fraction;
|
||||
var s = this.rgb;
|
||||
var d = other.rgb;
|
||||
var df = fraction;
|
||||
return MochiKit.Color.Color.fromRGB(
|
||||
(s.r * sf) + (d.r * df),
|
||||
(s.g * sf) + (d.g * df),
|
||||
(s.b * sf) + (d.b * df),
|
||||
(s.a * sf) + (d.a * df)
|
||||
);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.compareRGB */
|
||||
compareRGB: function (other) {
|
||||
var a = this.asRGB();
|
||||
var b = other.asRGB();
|
||||
return MochiKit.Base.compare(
|
||||
[a.r, a.g, a.b, a.a],
|
||||
[b.r, b.g, b.b, b.a]
|
||||
);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.isLight */
|
||||
isLight: function () {
|
||||
return this.asHSL().b > 0.5;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.isDark */
|
||||
isDark: function () {
|
||||
return (!this.isLight());
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.toHSLString */
|
||||
toHSLString: function () {
|
||||
var c = this.asHSL();
|
||||
var ccc = MochiKit.Color.clampColorComponent;
|
||||
var rval = this._hslString;
|
||||
if (!rval) {
|
||||
var mid = (
|
||||
ccc(c.h, 360).toFixed(0)
|
||||
+ "," + ccc(c.s, 100).toPrecision(4) + "%"
|
||||
+ "," + ccc(c.l, 100).toPrecision(4) + "%"
|
||||
);
|
||||
var a = c.a;
|
||||
if (a >= 1) {
|
||||
a = 1;
|
||||
rval = "hsl(" + mid + ")";
|
||||
} else {
|
||||
if (a <= 0) {
|
||||
a = 0;
|
||||
}
|
||||
rval = "hsla(" + mid + "," + a + ")";
|
||||
}
|
||||
this._hslString = rval;
|
||||
}
|
||||
return rval;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.toRGBString */
|
||||
toRGBString: function () {
|
||||
var c = this.rgb;
|
||||
var ccc = MochiKit.Color.clampColorComponent;
|
||||
var rval = this._rgbString;
|
||||
if (!rval) {
|
||||
var mid = (
|
||||
ccc(c.r, 255).toFixed(0)
|
||||
+ "," + ccc(c.g, 255).toFixed(0)
|
||||
+ "," + ccc(c.b, 255).toFixed(0)
|
||||
);
|
||||
if (c.a != 1) {
|
||||
rval = "rgba(" + mid + "," + c.a + ")";
|
||||
} else {
|
||||
rval = "rgb(" + mid + ")";
|
||||
}
|
||||
this._rgbString = rval;
|
||||
}
|
||||
return rval;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.asRGB */
|
||||
asRGB: function () {
|
||||
return MochiKit.Base.clone(this.rgb);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.toHexString */
|
||||
toHexString: function () {
|
||||
var m = MochiKit.Color;
|
||||
var c = this.rgb;
|
||||
var ccc = MochiKit.Color.clampColorComponent;
|
||||
var rval = this._hexString;
|
||||
if (!rval) {
|
||||
rval = ("#" +
|
||||
m.toColorPart(ccc(c.r, 255)) +
|
||||
m.toColorPart(ccc(c.g, 255)) +
|
||||
m.toColorPart(ccc(c.b, 255))
|
||||
);
|
||||
this._hexString = rval;
|
||||
}
|
||||
return rval;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.asHSV */
|
||||
asHSV: function () {
|
||||
var hsv = this.hsv;
|
||||
var c = this.rgb;
|
||||
if (typeof(hsv) == 'undefined' || hsv === null) {
|
||||
hsv = MochiKit.Color.rgbToHSV(this.rgb);
|
||||
this.hsv = hsv;
|
||||
}
|
||||
return MochiKit.Base.clone(hsv);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.asHSL */
|
||||
asHSL: function () {
|
||||
var hsl = this.hsl;
|
||||
var c = this.rgb;
|
||||
if (typeof(hsl) == 'undefined' || hsl === null) {
|
||||
hsl = MochiKit.Color.rgbToHSL(this.rgb);
|
||||
this.hsl = hsl;
|
||||
}
|
||||
return MochiKit.Base.clone(hsl);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.toString */
|
||||
toString: function () {
|
||||
return this.toRGBString();
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.prototype.repr */
|
||||
repr: function () {
|
||||
var c = this.rgb;
|
||||
var col = [c.r, c.g, c.b, c.a];
|
||||
return this.__class__.NAME + "(" + col.join(", ") + ")";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Constructor methods
|
||||
|
||||
MochiKit.Base.update(MochiKit.Color.Color, {
|
||||
/** @id MochiKit.Color.Color.fromRGB */
|
||||
fromRGB: function (red, green, blue, alpha) {
|
||||
// designated initializer
|
||||
var Color = MochiKit.Color.Color;
|
||||
if (arguments.length == 1) {
|
||||
var rgb = red;
|
||||
red = rgb.r;
|
||||
green = rgb.g;
|
||||
blue = rgb.b;
|
||||
if (typeof(rgb.a) == 'undefined') {
|
||||
alpha = undefined;
|
||||
} else {
|
||||
alpha = rgb.a;
|
||||
}
|
||||
}
|
||||
return new Color(red, green, blue, alpha);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.fromHSL */
|
||||
fromHSL: function (hue, saturation, lightness, alpha) {
|
||||
var m = MochiKit.Color;
|
||||
return m.Color.fromRGB(m.hslToRGB.apply(m, arguments));
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.fromHSV */
|
||||
fromHSV: function (hue, saturation, value, alpha) {
|
||||
var m = MochiKit.Color;
|
||||
return m.Color.fromRGB(m.hsvToRGB.apply(m, arguments));
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.fromName */
|
||||
fromName: function (name) {
|
||||
var Color = MochiKit.Color.Color;
|
||||
// Opera 9 seems to "quote" named colors(?!)
|
||||
if (name.charAt(0) == '"') {
|
||||
name = name.substr(1, name.length - 2);
|
||||
}
|
||||
var htmlColor = Color._namedColors[name.toLowerCase()];
|
||||
if (typeof(htmlColor) == 'string') {
|
||||
return Color.fromHexString(htmlColor);
|
||||
} else if (name == "transparent") {
|
||||
return Color.transparentColor();
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.fromString */
|
||||
fromString: function (colorString) {
|
||||
var self = MochiKit.Color.Color;
|
||||
var three = colorString.substr(0, 3);
|
||||
if (three == "rgb") {
|
||||
return self.fromRGBString(colorString);
|
||||
} else if (three == "hsl") {
|
||||
return self.fromHSLString(colorString);
|
||||
} else if (colorString.charAt(0) == "#") {
|
||||
return self.fromHexString(colorString);
|
||||
}
|
||||
return self.fromName(colorString);
|
||||
},
|
||||
|
||||
|
||||
/** @id MochiKit.Color.Color.fromHexString */
|
||||
fromHexString: function (hexCode) {
|
||||
if (hexCode.charAt(0) == '#') {
|
||||
hexCode = hexCode.substring(1);
|
||||
}
|
||||
var components = [];
|
||||
var i, hex;
|
||||
if (hexCode.length == 3) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
hex = hexCode.substr(i, 1);
|
||||
components.push(parseInt(hex + hex, 16) / 255.0);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 6; i += 2) {
|
||||
hex = hexCode.substr(i, 2);
|
||||
components.push(parseInt(hex, 16) / 255.0);
|
||||
}
|
||||
}
|
||||
var Color = MochiKit.Color.Color;
|
||||
return Color.fromRGB.apply(Color, components);
|
||||
},
|
||||
|
||||
|
||||
_fromColorString: function (pre, method, scales, colorCode) {
|
||||
// parses either HSL or RGB
|
||||
if (colorCode.indexOf(pre) === 0) {
|
||||
colorCode = colorCode.substring(colorCode.indexOf("(", 3) + 1, colorCode.length - 1);
|
||||
}
|
||||
var colorChunks = colorCode.split(/\s*,\s*/);
|
||||
var colorFloats = [];
|
||||
for (var i = 0; i < colorChunks.length; i++) {
|
||||
var c = colorChunks[i];
|
||||
var val;
|
||||
var three = c.substring(c.length - 3);
|
||||
if (c.charAt(c.length - 1) == '%') {
|
||||
val = 0.01 * parseFloat(c.substring(0, c.length - 1));
|
||||
} else if (three == "deg") {
|
||||
val = parseFloat(c) / 360.0;
|
||||
} else if (three == "rad") {
|
||||
val = parseFloat(c) / (Math.PI * 2);
|
||||
} else {
|
||||
val = scales[i] * parseFloat(c);
|
||||
}
|
||||
colorFloats.push(val);
|
||||
}
|
||||
return this[method].apply(this, colorFloats);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.fromComputedStyle */
|
||||
fromComputedStyle: function (elem, style) {
|
||||
var d = MochiKit.DOM;
|
||||
var cls = MochiKit.Color.Color;
|
||||
for (elem = d.getElement(elem); elem; elem = elem.parentNode) {
|
||||
var actualColor = MochiKit.Style.getStyle.apply(d, arguments);
|
||||
if (!actualColor) {
|
||||
continue;
|
||||
}
|
||||
var color = cls.fromString(actualColor);
|
||||
if (!color) {
|
||||
break;
|
||||
}
|
||||
if (color.asRGB().a > 0) {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.fromBackground */
|
||||
fromBackground: function (elem) {
|
||||
var cls = MochiKit.Color.Color;
|
||||
return cls.fromComputedStyle(
|
||||
elem, "backgroundColor", "background-color") || cls.whiteColor();
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.fromText */
|
||||
fromText: function (elem) {
|
||||
var cls = MochiKit.Color.Color;
|
||||
return cls.fromComputedStyle(
|
||||
elem, "color", "color") || cls.blackColor();
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.Color.namedColors */
|
||||
namedColors: function () {
|
||||
return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Module level functions
|
||||
|
||||
MochiKit.Base.update(MochiKit.Color, {
|
||||
/** @id MochiKit.Color.clampColorComponent */
|
||||
clampColorComponent: function (v, scale) {
|
||||
v *= scale;
|
||||
if (v < 0) {
|
||||
return 0;
|
||||
} else if (v > scale) {
|
||||
return scale;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
},
|
||||
|
||||
_hslValue: function (n1, n2, hue) {
|
||||
if (hue > 6.0) {
|
||||
hue -= 6.0;
|
||||
} else if (hue < 0.0) {
|
||||
hue += 6.0;
|
||||
}
|
||||
var val;
|
||||
if (hue < 1.0) {
|
||||
val = n1 + (n2 - n1) * hue;
|
||||
} else if (hue < 3.0) {
|
||||
val = n2;
|
||||
} else if (hue < 4.0) {
|
||||
val = n1 + (n2 - n1) * (4.0 - hue);
|
||||
} else {
|
||||
val = n1;
|
||||
}
|
||||
return val;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.hsvToRGB */
|
||||
hsvToRGB: function (hue, saturation, value, alpha) {
|
||||
if (arguments.length == 1) {
|
||||
var hsv = hue;
|
||||
hue = hsv.h;
|
||||
saturation = hsv.s;
|
||||
value = hsv.v;
|
||||
alpha = hsv.a;
|
||||
}
|
||||
var red;
|
||||
var green;
|
||||
var blue;
|
||||
if (saturation === 0) {
|
||||
red = value;
|
||||
green = value;
|
||||
blue = value;
|
||||
} else {
|
||||
var i = Math.floor(hue * 6);
|
||||
var f = (hue * 6) - i;
|
||||
var p = value * (1 - saturation);
|
||||
var q = value * (1 - (saturation * f));
|
||||
var t = value * (1 - (saturation * (1 - f)));
|
||||
switch (i) {
|
||||
case 1: red = q; green = value; blue = p; break;
|
||||
case 2: red = p; green = value; blue = t; break;
|
||||
case 3: red = p; green = q; blue = value; break;
|
||||
case 4: red = t; green = p; blue = value; break;
|
||||
case 5: red = value; green = p; blue = q; break;
|
||||
case 6: // fall through
|
||||
case 0: red = value; green = t; blue = p; break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
r: red,
|
||||
g: green,
|
||||
b: blue,
|
||||
a: alpha
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.hslToRGB */
|
||||
hslToRGB: function (hue, saturation, lightness, alpha) {
|
||||
if (arguments.length == 1) {
|
||||
var hsl = hue;
|
||||
hue = hsl.h;
|
||||
saturation = hsl.s;
|
||||
lightness = hsl.l;
|
||||
alpha = hsl.a;
|
||||
}
|
||||
var red;
|
||||
var green;
|
||||
var blue;
|
||||
if (saturation === 0) {
|
||||
red = lightness;
|
||||
green = lightness;
|
||||
blue = lightness;
|
||||
} else {
|
||||
var m2;
|
||||
if (lightness <= 0.5) {
|
||||
m2 = lightness * (1.0 + saturation);
|
||||
} else {
|
||||
m2 = lightness + saturation - (lightness * saturation);
|
||||
}
|
||||
var m1 = (2.0 * lightness) - m2;
|
||||
var f = MochiKit.Color._hslValue;
|
||||
var h6 = hue * 6.0;
|
||||
red = f(m1, m2, h6 + 2);
|
||||
green = f(m1, m2, h6);
|
||||
blue = f(m1, m2, h6 - 2);
|
||||
}
|
||||
return {
|
||||
r: red,
|
||||
g: green,
|
||||
b: blue,
|
||||
a: alpha
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.rgbToHSV */
|
||||
rgbToHSV: function (red, green, blue, alpha) {
|
||||
if (arguments.length == 1) {
|
||||
var rgb = red;
|
||||
red = rgb.r;
|
||||
green = rgb.g;
|
||||
blue = rgb.b;
|
||||
alpha = rgb.a;
|
||||
}
|
||||
var max = Math.max(Math.max(red, green), blue);
|
||||
var min = Math.min(Math.min(red, green), blue);
|
||||
var hue;
|
||||
var saturation;
|
||||
var value = max;
|
||||
if (min == max) {
|
||||
hue = 0;
|
||||
saturation = 0;
|
||||
} else {
|
||||
var delta = (max - min);
|
||||
saturation = delta / max;
|
||||
|
||||
if (red == max) {
|
||||
hue = (green - blue) / delta;
|
||||
} else if (green == max) {
|
||||
hue = 2 + ((blue - red) / delta);
|
||||
} else {
|
||||
hue = 4 + ((red - green) / delta);
|
||||
}
|
||||
hue /= 6;
|
||||
if (hue < 0) {
|
||||
hue += 1;
|
||||
}
|
||||
if (hue > 1) {
|
||||
hue -= 1;
|
||||
}
|
||||
}
|
||||
return {
|
||||
h: hue,
|
||||
s: saturation,
|
||||
v: value,
|
||||
a: alpha
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.rgbToHSL */
|
||||
rgbToHSL: function (red, green, blue, alpha) {
|
||||
if (arguments.length == 1) {
|
||||
var rgb = red;
|
||||
red = rgb.r;
|
||||
green = rgb.g;
|
||||
blue = rgb.b;
|
||||
alpha = rgb.a;
|
||||
}
|
||||
var max = Math.max(red, Math.max(green, blue));
|
||||
var min = Math.min(red, Math.min(green, blue));
|
||||
var hue;
|
||||
var saturation;
|
||||
var lightness = (max + min) / 2.0;
|
||||
var delta = max - min;
|
||||
if (delta === 0) {
|
||||
hue = 0;
|
||||
saturation = 0;
|
||||
} else {
|
||||
if (lightness <= 0.5) {
|
||||
saturation = delta / (max + min);
|
||||
} else {
|
||||
saturation = delta / (2 - max - min);
|
||||
}
|
||||
if (red == max) {
|
||||
hue = (green - blue) / delta;
|
||||
} else if (green == max) {
|
||||
hue = 2 + ((blue - red) / delta);
|
||||
} else {
|
||||
hue = 4 + ((red - green) / delta);
|
||||
}
|
||||
hue /= 6;
|
||||
if (hue < 0) {
|
||||
hue += 1;
|
||||
}
|
||||
if (hue > 1) {
|
||||
hue -= 1;
|
||||
}
|
||||
|
||||
}
|
||||
return {
|
||||
h: hue,
|
||||
s: saturation,
|
||||
l: lightness,
|
||||
a: alpha
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Color.toColorPart */
|
||||
toColorPart: function (num) {
|
||||
num = Math.round(num);
|
||||
var digits = num.toString(16);
|
||||
if (num < 16) {
|
||||
return '0' + digits;
|
||||
}
|
||||
return digits;
|
||||
},
|
||||
|
||||
__new__: function () {
|
||||
var m = MochiKit.Base;
|
||||
/** @id MochiKit.Color.fromRGBString */
|
||||
this.Color.fromRGBString = m.bind(
|
||||
this.Color._fromColorString, this.Color, "rgb", "fromRGB",
|
||||
[1.0/255.0, 1.0/255.0, 1.0/255.0, 1]
|
||||
);
|
||||
/** @id MochiKit.Color.fromHSLString */
|
||||
this.Color.fromHSLString = m.bind(
|
||||
this.Color._fromColorString, this.Color, "hsl", "fromHSL",
|
||||
[1.0/360.0, 0.01, 0.01, 1]
|
||||
);
|
||||
|
||||
var third = 1.0 / 3.0;
|
||||
/** @id MochiKit.Color.colors */
|
||||
var colors = {
|
||||
// NSColor colors plus transparent
|
||||
/** @id MochiKit.Color.blackColor */
|
||||
black: [0, 0, 0],
|
||||
/** @id MochiKit.Color.blueColor */
|
||||
blue: [0, 0, 1],
|
||||
/** @id MochiKit.Color.brownColor */
|
||||
brown: [0.6, 0.4, 0.2],
|
||||
/** @id MochiKit.Color.cyanColor */
|
||||
cyan: [0, 1, 1],
|
||||
/** @id MochiKit.Color.darkGrayColor */
|
||||
darkGray: [third, third, third],
|
||||
/** @id MochiKit.Color.grayColor */
|
||||
gray: [0.5, 0.5, 0.5],
|
||||
/** @id MochiKit.Color.greenColor */
|
||||
green: [0, 1, 0],
|
||||
/** @id MochiKit.Color.lightGrayColor */
|
||||
lightGray: [2 * third, 2 * third, 2 * third],
|
||||
/** @id MochiKit.Color.magentaColor */
|
||||
magenta: [1, 0, 1],
|
||||
/** @id MochiKit.Color.orangeColor */
|
||||
orange: [1, 0.5, 0],
|
||||
/** @id MochiKit.Color.purpleColor */
|
||||
purple: [0.5, 0, 0.5],
|
||||
/** @id MochiKit.Color.redColor */
|
||||
red: [1, 0, 0],
|
||||
/** @id MochiKit.Color.transparentColor */
|
||||
transparent: [0, 0, 0, 0],
|
||||
/** @id MochiKit.Color.whiteColor */
|
||||
white: [1, 1, 1],
|
||||
/** @id MochiKit.Color.yellowColor */
|
||||
yellow: [1, 1, 0]
|
||||
};
|
||||
|
||||
var makeColor = function (name, r, g, b, a) {
|
||||
var rval = this.fromRGB(r, g, b, a);
|
||||
this[name] = function () { return rval; };
|
||||
return rval;
|
||||
};
|
||||
|
||||
for (var k in colors) {
|
||||
var name = k + "Color";
|
||||
var bindArgs = m.concat(
|
||||
[makeColor, this.Color, name],
|
||||
colors[k]
|
||||
);
|
||||
this.Color[name] = m.bind.apply(null, bindArgs);
|
||||
}
|
||||
|
||||
var isColor = function () {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
if (!(arguments[i] instanceof Color)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
var compareColor = function (a, b) {
|
||||
return a.compareRGB(b);
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
|
||||
m.registerComparator(this.Color.NAME, isColor, compareColor);
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
MochiKit.Color.EXPORT = [
|
||||
"Color"
|
||||
];
|
||||
|
||||
MochiKit.Color.EXPORT_OK = [
|
||||
"clampColorComponent",
|
||||
"rgbToHSL",
|
||||
"hslToRGB",
|
||||
"rgbToHSV",
|
||||
"hsvToRGB",
|
||||
"toColorPart"
|
||||
];
|
||||
|
||||
MochiKit.Color.__new__();
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Color);
|
||||
|
||||
// Full table of css3 X11 colors <http://www.w3.org/TR/css3-color/#X11COLORS>
|
||||
|
||||
MochiKit.Color.Color._namedColors = {
|
||||
aliceblue: "#f0f8ff",
|
||||
antiquewhite: "#faebd7",
|
||||
aqua: "#00ffff",
|
||||
aquamarine: "#7fffd4",
|
||||
azure: "#f0ffff",
|
||||
beige: "#f5f5dc",
|
||||
bisque: "#ffe4c4",
|
||||
black: "#000000",
|
||||
blanchedalmond: "#ffebcd",
|
||||
blue: "#0000ff",
|
||||
blueviolet: "#8a2be2",
|
||||
brown: "#a52a2a",
|
||||
burlywood: "#deb887",
|
||||
cadetblue: "#5f9ea0",
|
||||
chartreuse: "#7fff00",
|
||||
chocolate: "#d2691e",
|
||||
coral: "#ff7f50",
|
||||
cornflowerblue: "#6495ed",
|
||||
cornsilk: "#fff8dc",
|
||||
crimson: "#dc143c",
|
||||
cyan: "#00ffff",
|
||||
darkblue: "#00008b",
|
||||
darkcyan: "#008b8b",
|
||||
darkgoldenrod: "#b8860b",
|
||||
darkgray: "#a9a9a9",
|
||||
darkgreen: "#006400",
|
||||
darkgrey: "#a9a9a9",
|
||||
darkkhaki: "#bdb76b",
|
||||
darkmagenta: "#8b008b",
|
||||
darkolivegreen: "#556b2f",
|
||||
darkorange: "#ff8c00",
|
||||
darkorchid: "#9932cc",
|
||||
darkred: "#8b0000",
|
||||
darksalmon: "#e9967a",
|
||||
darkseagreen: "#8fbc8f",
|
||||
darkslateblue: "#483d8b",
|
||||
darkslategray: "#2f4f4f",
|
||||
darkslategrey: "#2f4f4f",
|
||||
darkturquoise: "#00ced1",
|
||||
darkviolet: "#9400d3",
|
||||
deeppink: "#ff1493",
|
||||
deepskyblue: "#00bfff",
|
||||
dimgray: "#696969",
|
||||
dimgrey: "#696969",
|
||||
dodgerblue: "#1e90ff",
|
||||
firebrick: "#b22222",
|
||||
floralwhite: "#fffaf0",
|
||||
forestgreen: "#228b22",
|
||||
fuchsia: "#ff00ff",
|
||||
gainsboro: "#dcdcdc",
|
||||
ghostwhite: "#f8f8ff",
|
||||
gold: "#ffd700",
|
||||
goldenrod: "#daa520",
|
||||
gray: "#808080",
|
||||
green: "#008000",
|
||||
greenyellow: "#adff2f",
|
||||
grey: "#808080",
|
||||
honeydew: "#f0fff0",
|
||||
hotpink: "#ff69b4",
|
||||
indianred: "#cd5c5c",
|
||||
indigo: "#4b0082",
|
||||
ivory: "#fffff0",
|
||||
khaki: "#f0e68c",
|
||||
lavender: "#e6e6fa",
|
||||
lavenderblush: "#fff0f5",
|
||||
lawngreen: "#7cfc00",
|
||||
lemonchiffon: "#fffacd",
|
||||
lightblue: "#add8e6",
|
||||
lightcoral: "#f08080",
|
||||
lightcyan: "#e0ffff",
|
||||
lightgoldenrodyellow: "#fafad2",
|
||||
lightgray: "#d3d3d3",
|
||||
lightgreen: "#90ee90",
|
||||
lightgrey: "#d3d3d3",
|
||||
lightpink: "#ffb6c1",
|
||||
lightsalmon: "#ffa07a",
|
||||
lightseagreen: "#20b2aa",
|
||||
lightskyblue: "#87cefa",
|
||||
lightslategray: "#778899",
|
||||
lightslategrey: "#778899",
|
||||
lightsteelblue: "#b0c4de",
|
||||
lightyellow: "#ffffe0",
|
||||
lime: "#00ff00",
|
||||
limegreen: "#32cd32",
|
||||
linen: "#faf0e6",
|
||||
magenta: "#ff00ff",
|
||||
maroon: "#800000",
|
||||
mediumaquamarine: "#66cdaa",
|
||||
mediumblue: "#0000cd",
|
||||
mediumorchid: "#ba55d3",
|
||||
mediumpurple: "#9370db",
|
||||
mediumseagreen: "#3cb371",
|
||||
mediumslateblue: "#7b68ee",
|
||||
mediumspringgreen: "#00fa9a",
|
||||
mediumturquoise: "#48d1cc",
|
||||
mediumvioletred: "#c71585",
|
||||
midnightblue: "#191970",
|
||||
mintcream: "#f5fffa",
|
||||
mistyrose: "#ffe4e1",
|
||||
moccasin: "#ffe4b5",
|
||||
navajowhite: "#ffdead",
|
||||
navy: "#000080",
|
||||
oldlace: "#fdf5e6",
|
||||
olive: "#808000",
|
||||
olivedrab: "#6b8e23",
|
||||
orange: "#ffa500",
|
||||
orangered: "#ff4500",
|
||||
orchid: "#da70d6",
|
||||
palegoldenrod: "#eee8aa",
|
||||
palegreen: "#98fb98",
|
||||
paleturquoise: "#afeeee",
|
||||
palevioletred: "#db7093",
|
||||
papayawhip: "#ffefd5",
|
||||
peachpuff: "#ffdab9",
|
||||
peru: "#cd853f",
|
||||
pink: "#ffc0cb",
|
||||
plum: "#dda0dd",
|
||||
powderblue: "#b0e0e6",
|
||||
purple: "#800080",
|
||||
red: "#ff0000",
|
||||
rosybrown: "#bc8f8f",
|
||||
royalblue: "#4169e1",
|
||||
saddlebrown: "#8b4513",
|
||||
salmon: "#fa8072",
|
||||
sandybrown: "#f4a460",
|
||||
seagreen: "#2e8b57",
|
||||
seashell: "#fff5ee",
|
||||
sienna: "#a0522d",
|
||||
silver: "#c0c0c0",
|
||||
skyblue: "#87ceeb",
|
||||
slateblue: "#6a5acd",
|
||||
slategray: "#708090",
|
||||
slategrey: "#708090",
|
||||
snow: "#fffafa",
|
||||
springgreen: "#00ff7f",
|
||||
steelblue: "#4682b4",
|
||||
tan: "#d2b48c",
|
||||
teal: "#008080",
|
||||
thistle: "#d8bfd8",
|
||||
tomato: "#ff6347",
|
||||
turquoise: "#40e0d0",
|
||||
violet: "#ee82ee",
|
||||
wheat: "#f5deb3",
|
||||
white: "#ffffff",
|
||||
whitesmoke: "#f5f5f5",
|
||||
yellow: "#ffff00",
|
||||
yellowgreen: "#9acd32"
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,216 @@
|
|||
/***
|
||||
|
||||
MochiKit.DateTime 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.DateTime');
|
||||
}
|
||||
|
||||
if (typeof(MochiKit) == 'undefined') {
|
||||
MochiKit = {};
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.DateTime) == 'undefined') {
|
||||
MochiKit.DateTime = {};
|
||||
}
|
||||
|
||||
MochiKit.DateTime.NAME = "MochiKit.DateTime";
|
||||
MochiKit.DateTime.VERSION = "1.4";
|
||||
MochiKit.DateTime.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
MochiKit.DateTime.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
/** @id MochiKit.DateTime.isoDate */
|
||||
MochiKit.DateTime.isoDate = function (str) {
|
||||
str = str + "";
|
||||
if (typeof(str) != "string" || str.length === 0) {
|
||||
return null;
|
||||
}
|
||||
var iso = str.split('-');
|
||||
if (iso.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return new Date(iso[0], iso[1] - 1, iso[2]);
|
||||
};
|
||||
|
||||
MochiKit.DateTime._isoRegexp = /(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/;
|
||||
|
||||
/** @id MochiKit.DateTime.isoTimestamp */
|
||||
MochiKit.DateTime.isoTimestamp = function (str) {
|
||||
str = str + "";
|
||||
if (typeof(str) != "string" || str.length === 0) {
|
||||
return null;
|
||||
}
|
||||
var res = str.match(MochiKit.DateTime._isoRegexp);
|
||||
if (typeof(res) == "undefined" || res === null) {
|
||||
return null;
|
||||
}
|
||||
var year, month, day, hour, min, sec, msec;
|
||||
year = parseInt(res[1], 10);
|
||||
if (typeof(res[2]) == "undefined" || res[2] === '') {
|
||||
return new Date(year);
|
||||
}
|
||||
month = parseInt(res[2], 10) - 1;
|
||||
day = parseInt(res[3], 10);
|
||||
if (typeof(res[4]) == "undefined" || res[4] === '') {
|
||||
return new Date(year, month, day);
|
||||
}
|
||||
hour = parseInt(res[4], 10);
|
||||
min = parseInt(res[5], 10);
|
||||
sec = (typeof(res[6]) != "undefined" && res[6] !== '') ? parseInt(res[6], 10) : 0;
|
||||
if (typeof(res[7]) != "undefined" && res[7] !== '') {
|
||||
msec = Math.round(1000.0 * parseFloat("0." + res[7]));
|
||||
} else {
|
||||
msec = 0;
|
||||
}
|
||||
if ((typeof(res[8]) == "undefined" || res[8] === '') && (typeof(res[9]) == "undefined" || res[9] === '')) {
|
||||
return new Date(year, month, day, hour, min, sec, msec);
|
||||
}
|
||||
var ofs;
|
||||
if (typeof(res[9]) != "undefined" && res[9] !== '') {
|
||||
ofs = parseInt(res[10], 10) * 3600000;
|
||||
if (typeof(res[11]) != "undefined" && res[11] !== '') {
|
||||
ofs += parseInt(res[11], 10) * 60000;
|
||||
}
|
||||
if (res[9] == "-") {
|
||||
ofs = -ofs;
|
||||
}
|
||||
} else {
|
||||
ofs = 0;
|
||||
}
|
||||
return new Date(Date.UTC(year, month, day, hour, min, sec, msec) - ofs);
|
||||
};
|
||||
|
||||
/** @id MochiKit.DateTime.toISOTime */
|
||||
MochiKit.DateTime.toISOTime = function (date, realISO/* = false */) {
|
||||
if (typeof(date) == "undefined" || date === null) {
|
||||
return null;
|
||||
}
|
||||
var hh = date.getHours();
|
||||
var mm = date.getMinutes();
|
||||
var ss = date.getSeconds();
|
||||
var lst = [
|
||||
((realISO && (hh < 10)) ? "0" + hh : hh),
|
||||
((mm < 10) ? "0" + mm : mm),
|
||||
((ss < 10) ? "0" + ss : ss)
|
||||
];
|
||||
return lst.join(":");
|
||||
};
|
||||
|
||||
/** @id MochiKit.DateTime.toISOTimeStamp */
|
||||
MochiKit.DateTime.toISOTimestamp = function (date, realISO/* = false*/) {
|
||||
if (typeof(date) == "undefined" || date === null) {
|
||||
return null;
|
||||
}
|
||||
var sep = realISO ? "T" : " ";
|
||||
var foot = realISO ? "Z" : "";
|
||||
if (realISO) {
|
||||
date = new Date(date.getTime() + (date.getTimezoneOffset() * 60000));
|
||||
}
|
||||
return MochiKit.DateTime.toISODate(date) + sep + MochiKit.DateTime.toISOTime(date, realISO) + foot;
|
||||
};
|
||||
|
||||
/** @id MochiKit.DateTime.toISODate */
|
||||
MochiKit.DateTime.toISODate = function (date) {
|
||||
if (typeof(date) == "undefined" || date === null) {
|
||||
return null;
|
||||
}
|
||||
var _padTwo = MochiKit.DateTime._padTwo;
|
||||
return [
|
||||
date.getFullYear(),
|
||||
_padTwo(date.getMonth() + 1),
|
||||
_padTwo(date.getDate())
|
||||
].join("-");
|
||||
};
|
||||
|
||||
/** @id MochiKit.DateTime.americanDate */
|
||||
MochiKit.DateTime.americanDate = function (d) {
|
||||
d = d + "";
|
||||
if (typeof(d) != "string" || d.length === 0) {
|
||||
return null;
|
||||
}
|
||||
var a = d.split('/');
|
||||
return new Date(a[2], a[0] - 1, a[1]);
|
||||
};
|
||||
|
||||
MochiKit.DateTime._padTwo = function (n) {
|
||||
return (n > 9) ? n : "0" + n;
|
||||
};
|
||||
|
||||
/** @id MochiKit.DateTime.toPaddedAmericanDate */
|
||||
MochiKit.DateTime.toPaddedAmericanDate = function (d) {
|
||||
if (typeof(d) == "undefined" || d === null) {
|
||||
return null;
|
||||
}
|
||||
var _padTwo = MochiKit.DateTime._padTwo;
|
||||
return [
|
||||
_padTwo(d.getMonth() + 1),
|
||||
_padTwo(d.getDate()),
|
||||
d.getFullYear()
|
||||
].join('/');
|
||||
};
|
||||
|
||||
/** @id MochiKit.DateTime.toAmericanDate */
|
||||
MochiKit.DateTime.toAmericanDate = function (d) {
|
||||
if (typeof(d) == "undefined" || d === null) {
|
||||
return null;
|
||||
}
|
||||
return [d.getMonth() + 1, d.getDate(), d.getFullYear()].join('/');
|
||||
};
|
||||
|
||||
MochiKit.DateTime.EXPORT = [
|
||||
"isoDate",
|
||||
"isoTimestamp",
|
||||
"toISOTime",
|
||||
"toISOTimestamp",
|
||||
"toISODate",
|
||||
"americanDate",
|
||||
"toPaddedAmericanDate",
|
||||
"toAmericanDate"
|
||||
];
|
||||
|
||||
MochiKit.DateTime.EXPORT_OK = [];
|
||||
MochiKit.DateTime.EXPORT_TAGS = {
|
||||
":common": MochiKit.DateTime.EXPORT,
|
||||
":all": MochiKit.DateTime.EXPORT
|
||||
};
|
||||
|
||||
MochiKit.DateTime.__new__ = function () {
|
||||
// MochiKit.Base.nameFunctions(this);
|
||||
var base = this.NAME + ".";
|
||||
for (var k in this) {
|
||||
var o = this[k];
|
||||
if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
|
||||
try {
|
||||
o.NAME = base + k;
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.DateTime.__new__();
|
||||
|
||||
if (typeof(MochiKit.Base) != "undefined") {
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.DateTime);
|
||||
} else {
|
||||
(function (globals, module) {
|
||||
if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined')
|
||||
|| (MochiKit.__export__ === false)) {
|
||||
var all = module.EXPORT_TAGS[":all"];
|
||||
for (var i = 0; i < all.length; i++) {
|
||||
globals[all[i]] = module[all[i]];
|
||||
}
|
||||
}
|
||||
})(this, MochiKit.DateTime);
|
||||
}
|
|
@ -0,0 +1,824 @@
|
|||
/***
|
||||
MochiKit.DragAndDrop 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
Mochi-ized By Thomas Herve (_firstname_@nimail.org)
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.DragAndDrop');
|
||||
dojo.require('MochiKit.Base');
|
||||
dojo.require('MochiKit.DOM');
|
||||
dojo.require('MochiKit.Iter');
|
||||
dojo.require('MochiKit.Visual');
|
||||
dojo.require('MochiKit.Signal');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
JSAN.use("MochiKit.DOM", []);
|
||||
JSAN.use("MochiKit.Visual", []);
|
||||
JSAN.use("MochiKit.Iter", []);
|
||||
JSAN.use("MochiKit.Signal", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined' ||
|
||||
typeof(MochiKit.DOM) == 'undefined' ||
|
||||
typeof(MochiKit.Visual) == 'undefined' ||
|
||||
typeof(MochiKit.Signal) == 'undefined' ||
|
||||
typeof(MochiKit.Iter) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.DragAndDrop depends on MochiKit.Base, MochiKit.DOM, MochiKit.Visual, MochiKit.Signal and MochiKit.Iter!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.DragAndDrop) == 'undefined') {
|
||||
MochiKit.DragAndDrop = {};
|
||||
}
|
||||
|
||||
MochiKit.DragAndDrop.NAME = 'MochiKit.DragAndDrop';
|
||||
MochiKit.DragAndDrop.VERSION = '1.4';
|
||||
|
||||
MochiKit.DragAndDrop.__repr__ = function () {
|
||||
return '[' + this.NAME + ' ' + this.VERSION + ']';
|
||||
};
|
||||
|
||||
MochiKit.DragAndDrop.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
MochiKit.DragAndDrop.EXPORT = [
|
||||
"Droppable",
|
||||
"Draggable"
|
||||
];
|
||||
|
||||
MochiKit.DragAndDrop.EXPORT_OK = [
|
||||
"Droppables",
|
||||
"Draggables"
|
||||
];
|
||||
|
||||
MochiKit.DragAndDrop.Droppables = {
|
||||
/***
|
||||
|
||||
Manage all droppables. Shouldn't be used, use the Droppable object instead.
|
||||
|
||||
***/
|
||||
drops: [],
|
||||
|
||||
remove: function (element) {
|
||||
this.drops = MochiKit.Base.filter(function (d) {
|
||||
return d.element != MochiKit.DOM.getElement(element);
|
||||
}, this.drops);
|
||||
},
|
||||
|
||||
register: function (drop) {
|
||||
this.drops.push(drop);
|
||||
},
|
||||
|
||||
unregister: function (drop) {
|
||||
this.drops = MochiKit.Base.filter(function (d) {
|
||||
return d != drop;
|
||||
}, this.drops);
|
||||
},
|
||||
|
||||
prepare: function (element) {
|
||||
MochiKit.Base.map(function (drop) {
|
||||
if (drop.isAccepted(element)) {
|
||||
if (drop.options.activeclass) {
|
||||
MochiKit.DOM.addElementClass(drop.element,
|
||||
drop.options.activeclass);
|
||||
}
|
||||
drop.options.onactive(drop.element, element);
|
||||
}
|
||||
}, this.drops);
|
||||
},
|
||||
|
||||
findDeepestChild: function (drops) {
|
||||
deepest = drops[0];
|
||||
|
||||
for (i = 1; i < drops.length; ++i) {
|
||||
if (MochiKit.DOM.isParent(drops[i].element, deepest.element)) {
|
||||
deepest = drops[i];
|
||||
}
|
||||
}
|
||||
return deepest;
|
||||
},
|
||||
|
||||
show: function (point, element) {
|
||||
if (!this.drops.length) {
|
||||
return;
|
||||
}
|
||||
var affected = [];
|
||||
|
||||
if (this.last_active) {
|
||||
this.last_active.deactivate();
|
||||
}
|
||||
MochiKit.Iter.forEach(this.drops, function (drop) {
|
||||
if (drop.isAffected(point, element)) {
|
||||
affected.push(drop);
|
||||
}
|
||||
});
|
||||
if (affected.length > 0) {
|
||||
drop = this.findDeepestChild(affected);
|
||||
MochiKit.Position.within(drop.element, point.page.x, point.page.y);
|
||||
drop.options.onhover(element, drop.element,
|
||||
MochiKit.Position.overlap(drop.options.overlap, drop.element));
|
||||
drop.activate();
|
||||
}
|
||||
},
|
||||
|
||||
fire: function (event, element) {
|
||||
if (!this.last_active) {
|
||||
return;
|
||||
}
|
||||
MochiKit.Position.prepare();
|
||||
|
||||
if (this.last_active.isAffected(event.mouse(), element)) {
|
||||
this.last_active.options.ondrop(element,
|
||||
this.last_active.element, event);
|
||||
}
|
||||
},
|
||||
|
||||
reset: function (element) {
|
||||
MochiKit.Base.map(function (drop) {
|
||||
if (drop.options.activeclass) {
|
||||
MochiKit.DOM.removeElementClass(drop.element,
|
||||
drop.options.activeclass);
|
||||
}
|
||||
drop.options.ondesactive(drop.element, element);
|
||||
}, this.drops);
|
||||
if (this.last_active) {
|
||||
this.last_active.deactivate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.DragAndDrop.Droppable */
|
||||
MochiKit.DragAndDrop.Droppable = function (element, options) {
|
||||
var cls = arguments.callee;
|
||||
if (!(this instanceof cls)) {
|
||||
return new cls(element, options);
|
||||
}
|
||||
this.__init__(element, options);
|
||||
};
|
||||
|
||||
MochiKit.DragAndDrop.Droppable.prototype = {
|
||||
/***
|
||||
|
||||
A droppable object. Simple use is to create giving an element:
|
||||
|
||||
new MochiKit.DragAndDrop.Droppable('myelement');
|
||||
|
||||
Generally you'll want to define the 'ondrop' function and maybe the
|
||||
'accept' option to filter draggables.
|
||||
|
||||
***/
|
||||
__class__: MochiKit.DragAndDrop.Droppable,
|
||||
|
||||
__init__: function (element, /* optional */options) {
|
||||
var d = MochiKit.DOM;
|
||||
var b = MochiKit.Base;
|
||||
this.element = d.getElement(element);
|
||||
this.options = b.update({
|
||||
|
||||
/** @id MochiKit.DragAndDrop.greedy */
|
||||
greedy: true,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.hoverclass */
|
||||
hoverclass: null,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.activeclass */
|
||||
activeclass: null,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.hoverfunc */
|
||||
hoverfunc: b.noop,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.accept */
|
||||
accept: null,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.onactive */
|
||||
onactive: b.noop,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.ondesactive */
|
||||
ondesactive: b.noop,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.onhover */
|
||||
onhover: b.noop,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.ondrop */
|
||||
ondrop: b.noop,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.containment */
|
||||
containment: [],
|
||||
tree: false
|
||||
}, options || {});
|
||||
|
||||
// cache containers
|
||||
this.options._containers = [];
|
||||
b.map(MochiKit.Base.bind(function (c) {
|
||||
this.options._containers.push(d.getElement(c));
|
||||
}, this), this.options.containment);
|
||||
|
||||
d.makePositioned(this.element); // fix IE
|
||||
|
||||
MochiKit.DragAndDrop.Droppables.register(this);
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.isContained */
|
||||
isContained: function (element) {
|
||||
if (this.options._containers.length) {
|
||||
var containmentNode;
|
||||
if (this.options.tree) {
|
||||
containmentNode = element.treeNode;
|
||||
} else {
|
||||
containmentNode = element.parentNode;
|
||||
}
|
||||
return MochiKit.Iter.some(this.options._containers, function (c) {
|
||||
return containmentNode == c;
|
||||
});
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.isAccepted */
|
||||
isAccepted: function (element) {
|
||||
return ((!this.options.accept) || MochiKit.Iter.some(
|
||||
this.options.accept, function (c) {
|
||||
return MochiKit.DOM.hasElementClass(element, c);
|
||||
}));
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.isAffected */
|
||||
isAffected: function (point, element) {
|
||||
return ((this.element != element) &&
|
||||
this.isContained(element) &&
|
||||
this.isAccepted(element) &&
|
||||
MochiKit.Position.within(this.element, point.page.x,
|
||||
point.page.y));
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.deactivate */
|
||||
deactivate: function () {
|
||||
/***
|
||||
|
||||
A droppable is deactivate when a draggable has been over it and left.
|
||||
|
||||
***/
|
||||
if (this.options.hoverclass) {
|
||||
MochiKit.DOM.removeElementClass(this.element,
|
||||
this.options.hoverclass);
|
||||
}
|
||||
this.options.hoverfunc(this.element, false);
|
||||
MochiKit.DragAndDrop.Droppables.last_active = null;
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.activate */
|
||||
activate: function () {
|
||||
/***
|
||||
|
||||
A droppable is active when a draggable is over it.
|
||||
|
||||
***/
|
||||
if (this.options.hoverclass) {
|
||||
MochiKit.DOM.addElementClass(this.element, this.options.hoverclass);
|
||||
}
|
||||
this.options.hoverfunc(this.element, true);
|
||||
MochiKit.DragAndDrop.Droppables.last_active = this;
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.destroy */
|
||||
destroy: function () {
|
||||
/***
|
||||
|
||||
Delete this droppable.
|
||||
|
||||
***/
|
||||
MochiKit.DragAndDrop.Droppables.unregister(this);
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.repr */
|
||||
repr: function () {
|
||||
return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.DragAndDrop.Draggables = {
|
||||
/***
|
||||
|
||||
Manage draggables elements. Not intended to direct use.
|
||||
|
||||
***/
|
||||
drags: [],
|
||||
|
||||
register: function (draggable) {
|
||||
if (this.drags.length === 0) {
|
||||
var conn = MochiKit.Signal.connect;
|
||||
this.eventMouseUp = conn(document, 'onmouseup', this, this.endDrag);
|
||||
this.eventMouseMove = conn(document, 'onmousemove', this,
|
||||
this.updateDrag);
|
||||
this.eventKeypress = conn(document, 'onkeypress', this,
|
||||
this.keyPress);
|
||||
}
|
||||
this.drags.push(draggable);
|
||||
},
|
||||
|
||||
unregister: function (draggable) {
|
||||
this.drags = MochiKit.Base.filter(function (d) {
|
||||
return d != draggable;
|
||||
}, this.drags);
|
||||
if (this.drags.length === 0) {
|
||||
var disc = MochiKit.Signal.disconnect;
|
||||
disc(this.eventMouseUp);
|
||||
disc(this.eventMouseMove);
|
||||
disc(this.eventKeypress);
|
||||
}
|
||||
},
|
||||
|
||||
activate: function (draggable) {
|
||||
// allows keypress events if window is not currently focused
|
||||
// fails for Safari
|
||||
window.focus();
|
||||
this.activeDraggable = draggable;
|
||||
},
|
||||
|
||||
deactivate: function () {
|
||||
this.activeDraggable = null;
|
||||
},
|
||||
|
||||
updateDrag: function (event) {
|
||||
if (!this.activeDraggable) {
|
||||
return;
|
||||
}
|
||||
var pointer = event.mouse();
|
||||
// Mozilla-based browsers fire successive mousemove events with
|
||||
// the same coordinates, prevent needless redrawing (moz bug?)
|
||||
if (this._lastPointer && (MochiKit.Base.repr(this._lastPointer.page) ==
|
||||
MochiKit.Base.repr(pointer.page))) {
|
||||
return;
|
||||
}
|
||||
this._lastPointer = pointer;
|
||||
this.activeDraggable.updateDrag(event, pointer);
|
||||
},
|
||||
|
||||
endDrag: function (event) {
|
||||
if (!this.activeDraggable) {
|
||||
return;
|
||||
}
|
||||
this._lastPointer = null;
|
||||
this.activeDraggable.endDrag(event);
|
||||
this.activeDraggable = null;
|
||||
},
|
||||
|
||||
keyPress: function (event) {
|
||||
if (this.activeDraggable) {
|
||||
this.activeDraggable.keyPress(event);
|
||||
}
|
||||
},
|
||||
|
||||
notify: function (eventName, draggable, event) {
|
||||
MochiKit.Signal.signal(this, eventName, draggable, event);
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.DragAndDrop.Draggable */
|
||||
MochiKit.DragAndDrop.Draggable = function (element, options) {
|
||||
var cls = arguments.callee;
|
||||
if (!(this instanceof cls)) {
|
||||
return new cls(element, options);
|
||||
}
|
||||
this.__init__(element, options);
|
||||
};
|
||||
|
||||
MochiKit.DragAndDrop.Draggable.prototype = {
|
||||
/***
|
||||
|
||||
A draggable object. Simple instantiate :
|
||||
|
||||
new MochiKit.DragAndDrop.Draggable('myelement');
|
||||
|
||||
***/
|
||||
__class__ : MochiKit.DragAndDrop.Draggable,
|
||||
|
||||
__init__: function (element, /* optional */options) {
|
||||
var v = MochiKit.Visual;
|
||||
var b = MochiKit.Base;
|
||||
options = b.update({
|
||||
|
||||
/** @id MochiKit.DragAndDrop.handle */
|
||||
handle: false,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.starteffect */
|
||||
starteffect: function (innerelement) {
|
||||
this._savedOpacity = MochiKit.Style.getStyle(innerelement, 'opacity') || 1.0;
|
||||
new v.Opacity(innerelement, {duration:0.2, from:this._savedOpacity, to:0.7});
|
||||
},
|
||||
/** @id MochiKit.DragAndDrop.reverteffect */
|
||||
reverteffect: function (innerelement, top_offset, left_offset) {
|
||||
var dur = Math.sqrt(Math.abs(top_offset^2) +
|
||||
Math.abs(left_offset^2))*0.02;
|
||||
return new v.Move(innerelement,
|
||||
{x: -left_offset, y: -top_offset, duration: dur});
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.endeffect */
|
||||
endeffect: function (innerelement) {
|
||||
new v.Opacity(innerelement, {duration:0.2, from:0.7, to:this._savedOpacity});
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.onchange */
|
||||
onchange: b.noop,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.zindex */
|
||||
zindex: 1000,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.revert */
|
||||
revert: false,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.scroll */
|
||||
scroll: false,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.scrollSensitivity */
|
||||
scrollSensitivity: 20,
|
||||
|
||||
/** @id MochiKit.DragAndDrop.scrollSpeed */
|
||||
scrollSpeed: 15,
|
||||
// false, or xy or [x, y] or function (x, y){return [x, y];}
|
||||
|
||||
/** @id MochiKit.DragAndDrop.snap */
|
||||
snap: false
|
||||
}, options || {});
|
||||
|
||||
var d = MochiKit.DOM;
|
||||
this.element = d.getElement(element);
|
||||
|
||||
if (options.handle && (typeof(options.handle) == 'string')) {
|
||||
this.handle = d.getFirstElementByTagAndClassName(null,
|
||||
options.handle, this.element);
|
||||
}
|
||||
if (!this.handle) {
|
||||
this.handle = d.getElement(options.handle);
|
||||
}
|
||||
if (!this.handle) {
|
||||
this.handle = this.element;
|
||||
}
|
||||
|
||||
if (options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
|
||||
options.scroll = d.getElement(options.scroll);
|
||||
this._isScrollChild = MochiKit.DOM.isChildNode(this.element, options.scroll);
|
||||
}
|
||||
|
||||
d.makePositioned(this.element); // fix IE
|
||||
|
||||
this.delta = this.currentDelta();
|
||||
this.options = options;
|
||||
this.dragging = false;
|
||||
|
||||
this.eventMouseDown = MochiKit.Signal.connect(this.handle,
|
||||
'onmousedown', this, this.initDrag);
|
||||
MochiKit.DragAndDrop.Draggables.register(this);
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.destroy */
|
||||
destroy: function () {
|
||||
MochiKit.Signal.disconnect(this.eventMouseDown);
|
||||
MochiKit.DragAndDrop.Draggables.unregister(this);
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.currentDelta */
|
||||
currentDelta: function () {
|
||||
var s = MochiKit.Style.getStyle;
|
||||
return [
|
||||
parseInt(s(this.element, 'left') || '0'),
|
||||
parseInt(s(this.element, 'top') || '0')];
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.initDrag */
|
||||
initDrag: function (event) {
|
||||
if (!event.mouse().button.left) {
|
||||
return;
|
||||
}
|
||||
// abort on form elements, fixes a Firefox issue
|
||||
var src = event.target();
|
||||
var tagName = (src.tagName || '').toUpperCase();
|
||||
if (tagName === 'INPUT' || tagName === 'SELECT' ||
|
||||
tagName === 'OPTION' || tagName === 'BUTTON' ||
|
||||
tagName === 'TEXTAREA') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._revert) {
|
||||
this._revert.cancel();
|
||||
this._revert = null;
|
||||
}
|
||||
|
||||
var pointer = event.mouse();
|
||||
var pos = MochiKit.Position.cumulativeOffset(this.element);
|
||||
this.offset = [pointer.page.x - pos.x, pointer.page.y - pos.y];
|
||||
|
||||
MochiKit.DragAndDrop.Draggables.activate(this);
|
||||
event.stop();
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.startDrag */
|
||||
startDrag: function (event) {
|
||||
this.dragging = true;
|
||||
if (this.options.selectclass) {
|
||||
MochiKit.DOM.addElementClass(this.element,
|
||||
this.options.selectclass);
|
||||
}
|
||||
if (this.options.zindex) {
|
||||
this.originalZ = parseInt(MochiKit.Style.getStyle(this.element,
|
||||
'z-index') || '0');
|
||||
this.element.style.zIndex = this.options.zindex;
|
||||
}
|
||||
|
||||
if (this.options.ghosting) {
|
||||
this._clone = this.element.cloneNode(true);
|
||||
this.ghostPosition = MochiKit.Position.absolutize(this.element);
|
||||
this.element.parentNode.insertBefore(this._clone, this.element);
|
||||
}
|
||||
|
||||
if (this.options.scroll) {
|
||||
if (this.options.scroll == window) {
|
||||
var where = this._getWindowScroll(this.options.scroll);
|
||||
this.originalScrollLeft = where.left;
|
||||
this.originalScrollTop = where.top;
|
||||
} else {
|
||||
this.originalScrollLeft = this.options.scroll.scrollLeft;
|
||||
this.originalScrollTop = this.options.scroll.scrollTop;
|
||||
}
|
||||
}
|
||||
|
||||
MochiKit.DragAndDrop.Droppables.prepare(this.element);
|
||||
MochiKit.DragAndDrop.Draggables.notify('start', this, event);
|
||||
if (this.options.starteffect) {
|
||||
this.options.starteffect(this.element);
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.updateDrag */
|
||||
updateDrag: function (event, pointer) {
|
||||
if (!this.dragging) {
|
||||
this.startDrag(event);
|
||||
}
|
||||
MochiKit.Position.prepare();
|
||||
MochiKit.DragAndDrop.Droppables.show(pointer, this.element);
|
||||
MochiKit.DragAndDrop.Draggables.notify('drag', this, event);
|
||||
this.draw(pointer);
|
||||
this.options.onchange(this);
|
||||
|
||||
if (this.options.scroll) {
|
||||
this.stopScrolling();
|
||||
var p, q;
|
||||
if (this.options.scroll == window) {
|
||||
var s = this._getWindowScroll(this.options.scroll);
|
||||
p = new MochiKit.Style.Coordinates(s.left, s.top);
|
||||
q = new MochiKit.Style.Coordinates(s.left + s.width,
|
||||
s.top + s.height);
|
||||
} else {
|
||||
p = MochiKit.Position.page(this.options.scroll);
|
||||
p.x += this.options.scroll.scrollLeft;
|
||||
p.y += this.options.scroll.scrollTop;
|
||||
p.x += (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0);
|
||||
p.y += (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
|
||||
q = new MochiKit.Style.Coordinates(p.x + this.options.scroll.offsetWidth,
|
||||
p.y + this.options.scroll.offsetHeight);
|
||||
}
|
||||
var speed = [0, 0];
|
||||
if (pointer.page.x > (q.x - this.options.scrollSensitivity)) {
|
||||
speed[0] = pointer.page.x - (q.x - this.options.scrollSensitivity);
|
||||
} else if (pointer.page.x < (p.x + this.options.scrollSensitivity)) {
|
||||
speed[0] = pointer.page.x - (p.x + this.options.scrollSensitivity);
|
||||
}
|
||||
if (pointer.page.y > (q.y - this.options.scrollSensitivity)) {
|
||||
speed[1] = pointer.page.y - (q.y - this.options.scrollSensitivity);
|
||||
} else if (pointer.page.y < (p.y + this.options.scrollSensitivity)) {
|
||||
speed[1] = pointer.page.y - (p.y + this.options.scrollSensitivity);
|
||||
}
|
||||
this.startScrolling(speed);
|
||||
}
|
||||
|
||||
// fix AppleWebKit rendering
|
||||
if (/AppleWebKit'/.test(navigator.appVersion)) {
|
||||
window.scrollBy(0, 0);
|
||||
}
|
||||
event.stop();
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.finishDrag */
|
||||
finishDrag: function (event, success) {
|
||||
var dr = MochiKit.DragAndDrop;
|
||||
this.dragging = false;
|
||||
if (this.options.selectclass) {
|
||||
MochiKit.DOM.removeElementClass(this.element,
|
||||
this.options.selectclass);
|
||||
}
|
||||
|
||||
if (this.options.ghosting) {
|
||||
// XXX: from a user point of view, it would be better to remove
|
||||
// the node only *after* the MochiKit.Visual.Move end when used
|
||||
// with revert.
|
||||
MochiKit.Position.relativize(this.element, this.ghostPosition);
|
||||
MochiKit.DOM.removeElement(this._clone);
|
||||
this._clone = null;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
dr.Droppables.fire(event, this.element);
|
||||
}
|
||||
dr.Draggables.notify('end', this, event);
|
||||
|
||||
var revert = this.options.revert;
|
||||
if (revert && typeof(revert) == 'function') {
|
||||
revert = revert(this.element);
|
||||
}
|
||||
|
||||
var d = this.currentDelta();
|
||||
if (revert && this.options.reverteffect) {
|
||||
this._revert = this.options.reverteffect(this.element,
|
||||
d[1] - this.delta[1], d[0] - this.delta[0]);
|
||||
} else {
|
||||
this.delta = d;
|
||||
}
|
||||
|
||||
if (this.options.zindex) {
|
||||
this.element.style.zIndex = this.originalZ;
|
||||
}
|
||||
|
||||
if (this.options.endeffect) {
|
||||
this.options.endeffect(this.element);
|
||||
}
|
||||
|
||||
dr.Draggables.deactivate();
|
||||
dr.Droppables.reset(this.element);
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.keyPress */
|
||||
keyPress: function (event) {
|
||||
if (event.key().string != "KEY_ESCAPE") {
|
||||
return;
|
||||
}
|
||||
this.finishDrag(event, false);
|
||||
event.stop();
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.endDrag */
|
||||
endDrag: function (event) {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
this.stopScrolling();
|
||||
this.finishDrag(event, true);
|
||||
event.stop();
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.draw */
|
||||
draw: function (point) {
|
||||
var pos = MochiKit.Position.cumulativeOffset(this.element);
|
||||
var d = this.currentDelta();
|
||||
pos.x -= d[0];
|
||||
pos.y -= d[1];
|
||||
|
||||
if (this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
|
||||
pos.x -= this.options.scroll.scrollLeft - this.originalScrollLeft;
|
||||
pos.y -= this.options.scroll.scrollTop - this.originalScrollTop;
|
||||
}
|
||||
|
||||
var p = [point.page.x - pos.x - this.offset[0],
|
||||
point.page.y - pos.y - this.offset[1]];
|
||||
|
||||
if (this.options.snap) {
|
||||
if (typeof(this.options.snap) == 'function') {
|
||||
p = this.options.snap(p[0], p[1]);
|
||||
} else {
|
||||
if (this.options.snap instanceof Array) {
|
||||
var i = -1;
|
||||
p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
|
||||
i += 1;
|
||||
return Math.round(v/this.options.snap[i]) *
|
||||
this.options.snap[i];
|
||||
}, this), p);
|
||||
} else {
|
||||
p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
|
||||
return Math.round(v/this.options.snap) *
|
||||
this.options.snap;
|
||||
}, this), p);
|
||||
}
|
||||
}
|
||||
}
|
||||
var style = this.element.style;
|
||||
if ((!this.options.constraint) ||
|
||||
(this.options.constraint == 'horizontal')) {
|
||||
style.left = p[0] + 'px';
|
||||
}
|
||||
if ((!this.options.constraint) ||
|
||||
(this.options.constraint == 'vertical')) {
|
||||
style.top = p[1] + 'px';
|
||||
}
|
||||
if (style.visibility == 'hidden') {
|
||||
style.visibility = ''; // fix gecko rendering
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.stopScrolling */
|
||||
stopScrolling: function () {
|
||||
if (this.scrollInterval) {
|
||||
clearInterval(this.scrollInterval);
|
||||
this.scrollInterval = null;
|
||||
MochiKit.DragAndDrop.Draggables._lastScrollPointer = null;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.startScrolling */
|
||||
startScrolling: function (speed) {
|
||||
if (!speed[0] && !speed[1]) {
|
||||
return;
|
||||
}
|
||||
this.scrollSpeed = [speed[0] * this.options.scrollSpeed,
|
||||
speed[1] * this.options.scrollSpeed];
|
||||
this.lastScrolled = new Date();
|
||||
this.scrollInterval = setInterval(MochiKit.Base.bind(this.scroll, this), 10);
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.scroll */
|
||||
scroll: function () {
|
||||
var current = new Date();
|
||||
var delta = current - this.lastScrolled;
|
||||
this.lastScrolled = current;
|
||||
|
||||
if (this.options.scroll == window) {
|
||||
var s = this._getWindowScroll(this.options.scroll);
|
||||
if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
|
||||
var dm = delta / 1000;
|
||||
this.options.scroll.scrollTo(s.left + dm * this.scrollSpeed[0],
|
||||
s.top + dm * this.scrollSpeed[1]);
|
||||
}
|
||||
} else {
|
||||
this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
|
||||
this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
|
||||
}
|
||||
|
||||
var d = MochiKit.DragAndDrop;
|
||||
|
||||
MochiKit.Position.prepare();
|
||||
d.Droppables.show(d.Draggables._lastPointer, this.element);
|
||||
d.Draggables.notify('drag', this);
|
||||
if (this._isScrollChild) {
|
||||
d.Draggables._lastScrollPointer = d.Draggables._lastScrollPointer || d.Draggables._lastPointer;
|
||||
d.Draggables._lastScrollPointer.x += this.scrollSpeed[0] * delta / 1000;
|
||||
d.Draggables._lastScrollPointer.y += this.scrollSpeed[1] * delta / 1000;
|
||||
if (d.Draggables._lastScrollPointer.x < 0) {
|
||||
d.Draggables._lastScrollPointer.x = 0;
|
||||
}
|
||||
if (d.Draggables._lastScrollPointer.y < 0) {
|
||||
d.Draggables._lastScrollPointer.y = 0;
|
||||
}
|
||||
this.draw(d.Draggables._lastScrollPointer);
|
||||
}
|
||||
|
||||
this.options.onchange(this);
|
||||
},
|
||||
|
||||
_getWindowScroll: function (win) {
|
||||
var vp, w, h;
|
||||
MochiKit.DOM.withWindow(win, function () {
|
||||
vp = MochiKit.Style.getViewportPosition(win.document);
|
||||
});
|
||||
if (win.innerWidth) {
|
||||
w = win.innerWidth;
|
||||
h = win.innerHeight;
|
||||
} else if (win.document.documentElement && win.document.documentElement.clientWidth) {
|
||||
w = win.document.documentElement.clientWidth;
|
||||
h = win.document.documentElement.clientHeight;
|
||||
} else {
|
||||
w = win.document.body.offsetWidth;
|
||||
h = win.document.body.offsetHeight;
|
||||
}
|
||||
return {top: vp.x, left: vp.y, width: w, height: h};
|
||||
},
|
||||
|
||||
/** @id MochiKit.DragAndDrop.repr */
|
||||
repr: function () {
|
||||
return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.DragAndDrop.__new__ = function () {
|
||||
MochiKit.Base.nameFunctions(this);
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": MochiKit.Base.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
};
|
||||
|
||||
MochiKit.DragAndDrop.__new__();
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.DragAndDrop);
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
/***
|
||||
|
||||
MochiKit.Format 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Format');
|
||||
}
|
||||
|
||||
if (typeof(MochiKit) == 'undefined') {
|
||||
MochiKit = {};
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Format) == 'undefined') {
|
||||
MochiKit.Format = {};
|
||||
}
|
||||
|
||||
MochiKit.Format.NAME = "MochiKit.Format";
|
||||
MochiKit.Format.VERSION = "1.4";
|
||||
MochiKit.Format.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
MochiKit.Format.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
MochiKit.Format._numberFormatter = function (placeholder, header, footer, locale, isPercent, precision, leadingZeros, separatorAt, trailingZeros) {
|
||||
return function (num) {
|
||||
num = parseFloat(num);
|
||||
if (typeof(num) == "undefined" || num === null || isNaN(num)) {
|
||||
return placeholder;
|
||||
}
|
||||
var curheader = header;
|
||||
var curfooter = footer;
|
||||
if (num < 0) {
|
||||
num = -num;
|
||||
} else {
|
||||
curheader = curheader.replace(/-/, "");
|
||||
}
|
||||
var me = arguments.callee;
|
||||
var fmt = MochiKit.Format.formatLocale(locale);
|
||||
if (isPercent) {
|
||||
num = num * 100.0;
|
||||
curfooter = fmt.percent + curfooter;
|
||||
}
|
||||
num = MochiKit.Format.roundToFixed(num, precision);
|
||||
var parts = num.split(/\./);
|
||||
var whole = parts[0];
|
||||
var frac = (parts.length == 1) ? "" : parts[1];
|
||||
var res = "";
|
||||
while (whole.length < leadingZeros) {
|
||||
whole = "0" + whole;
|
||||
}
|
||||
if (separatorAt) {
|
||||
while (whole.length > separatorAt) {
|
||||
var i = whole.length - separatorAt;
|
||||
//res = res + fmt.separator + whole.substring(i, whole.length);
|
||||
res = fmt.separator + whole.substring(i, whole.length) + res;
|
||||
whole = whole.substring(0, i);
|
||||
}
|
||||
}
|
||||
res = whole + res;
|
||||
if (precision > 0) {
|
||||
while (frac.length < trailingZeros) {
|
||||
frac = frac + "0";
|
||||
}
|
||||
res = res + fmt.decimal + frac;
|
||||
}
|
||||
return curheader + res + curfooter;
|
||||
};
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.numberFormatter */
|
||||
MochiKit.Format.numberFormatter = function (pattern, placeholder/* = "" */, locale/* = "default" */) {
|
||||
// http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html
|
||||
// | 0 | leading or trailing zeros
|
||||
// | # | just the number
|
||||
// | , | separator
|
||||
// | . | decimal separator
|
||||
// | % | Multiply by 100 and format as percent
|
||||
if (typeof(placeholder) == "undefined") {
|
||||
placeholder = "";
|
||||
}
|
||||
var match = pattern.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
|
||||
if (!match) {
|
||||
throw TypeError("Invalid pattern");
|
||||
}
|
||||
var header = pattern.substr(0, match.index);
|
||||
var footer = pattern.substr(match.index + match[0].length);
|
||||
if (header.search(/-/) == -1) {
|
||||
header = header + "-";
|
||||
}
|
||||
var whole = match[1];
|
||||
var frac = (typeof(match[2]) == "string" && match[2] != "") ? match[2] : "";
|
||||
var isPercent = (typeof(match[3]) == "string" && match[3] != "");
|
||||
var tmp = whole.split(/,/);
|
||||
var separatorAt;
|
||||
if (typeof(locale) == "undefined") {
|
||||
locale = "default";
|
||||
}
|
||||
if (tmp.length == 1) {
|
||||
separatorAt = null;
|
||||
} else {
|
||||
separatorAt = tmp[1].length;
|
||||
}
|
||||
var leadingZeros = whole.length - whole.replace(/0/g, "").length;
|
||||
var trailingZeros = frac.length - frac.replace(/0/g, "").length;
|
||||
var precision = frac.length;
|
||||
var rval = MochiKit.Format._numberFormatter(
|
||||
placeholder, header, footer, locale, isPercent, precision,
|
||||
leadingZeros, separatorAt, trailingZeros
|
||||
);
|
||||
var m = MochiKit.Base;
|
||||
if (m) {
|
||||
var fn = arguments.callee;
|
||||
var args = m.concat(arguments);
|
||||
rval.repr = function () {
|
||||
return [
|
||||
self.NAME,
|
||||
"(",
|
||||
map(m.repr, args).join(", "),
|
||||
")"
|
||||
].join("");
|
||||
};
|
||||
}
|
||||
return rval;
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.formatLocale */
|
||||
MochiKit.Format.formatLocale = function (locale) {
|
||||
if (typeof(locale) == "undefined" || locale === null) {
|
||||
locale = "default";
|
||||
}
|
||||
if (typeof(locale) == "string") {
|
||||
var rval = MochiKit.Format.LOCALE[locale];
|
||||
if (typeof(rval) == "string") {
|
||||
rval = arguments.callee(rval);
|
||||
MochiKit.Format.LOCALE[locale] = rval;
|
||||
}
|
||||
return rval;
|
||||
} else {
|
||||
return locale;
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.twoDigitAverage */
|
||||
MochiKit.Format.twoDigitAverage = function (numerator, denominator) {
|
||||
if (denominator) {
|
||||
var res = numerator / denominator;
|
||||
if (!isNaN(res)) {
|
||||
return MochiKit.Format.twoDigitFloat(numerator / denominator);
|
||||
}
|
||||
}
|
||||
return "0";
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.twoDigitFloat */
|
||||
MochiKit.Format.twoDigitFloat = function (someFloat) {
|
||||
var sign = (someFloat < 0 ? '-' : '');
|
||||
var s = Math.floor(Math.abs(someFloat) * 100).toString();
|
||||
if (s == '0') {
|
||||
return s;
|
||||
}
|
||||
if (s.length < 3) {
|
||||
while (s.charAt(s.length - 1) == '0') {
|
||||
s = s.substring(0, s.length - 1);
|
||||
}
|
||||
return sign + '0.' + s;
|
||||
}
|
||||
var head = sign + s.substring(0, s.length - 2);
|
||||
var tail = s.substring(s.length - 2, s.length);
|
||||
if (tail == '00') {
|
||||
return head;
|
||||
} else if (tail.charAt(1) == '0') {
|
||||
return head + '.' + tail.charAt(0);
|
||||
} else {
|
||||
return head + '.' + tail;
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.lstrip */
|
||||
MochiKit.Format.lstrip = function (str, /* optional */chars) {
|
||||
str = str + "";
|
||||
if (typeof(str) != "string") {
|
||||
return null;
|
||||
}
|
||||
if (!chars) {
|
||||
return str.replace(/^\s+/, "");
|
||||
} else {
|
||||
return str.replace(new RegExp("^[" + chars + "]+"), "");
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.rstrip */
|
||||
MochiKit.Format.rstrip = function (str, /* optional */chars) {
|
||||
str = str + "";
|
||||
if (typeof(str) != "string") {
|
||||
return null;
|
||||
}
|
||||
if (!chars) {
|
||||
return str.replace(/\s+$/, "");
|
||||
} else {
|
||||
return str.replace(new RegExp("[" + chars + "]+$"), "");
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.strip */
|
||||
MochiKit.Format.strip = function (str, /* optional */chars) {
|
||||
var self = MochiKit.Format;
|
||||
return self.rstrip(self.lstrip(str, chars), chars);
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.truncToFixed */
|
||||
MochiKit.Format.truncToFixed = function (aNumber, precision) {
|
||||
aNumber = Math.floor(aNumber * Math.pow(10, precision));
|
||||
var res = (aNumber * Math.pow(10, -precision)).toFixed(precision);
|
||||
if (res.charAt(0) == ".") {
|
||||
res = "0" + res;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.roundToFixed */
|
||||
MochiKit.Format.roundToFixed = function (aNumber, precision) {
|
||||
return MochiKit.Format.truncToFixed(
|
||||
aNumber + 0.5 * Math.pow(10, -precision),
|
||||
precision
|
||||
);
|
||||
};
|
||||
|
||||
/** @id MochiKit.Format.percentFormat */
|
||||
MochiKit.Format.percentFormat = function (someFloat) {
|
||||
return MochiKit.Format.twoDigitFloat(100 * someFloat) + '%';
|
||||
};
|
||||
|
||||
MochiKit.Format.EXPORT = [
|
||||
"truncToFixed",
|
||||
"roundToFixed",
|
||||
"numberFormatter",
|
||||
"formatLocale",
|
||||
"twoDigitAverage",
|
||||
"twoDigitFloat",
|
||||
"percentFormat",
|
||||
"lstrip",
|
||||
"rstrip",
|
||||
"strip"
|
||||
];
|
||||
|
||||
MochiKit.Format.LOCALE = {
|
||||
en_US: {separator: ",", decimal: ".", percent: "%"},
|
||||
de_DE: {separator: ".", decimal: ",", percent: "%"},
|
||||
fr_FR: {separator: " ", decimal: ",", percent: "%"},
|
||||
"default": "en_US"
|
||||
};
|
||||
|
||||
MochiKit.Format.EXPORT_OK = [];
|
||||
MochiKit.Format.EXPORT_TAGS = {
|
||||
':all': MochiKit.Format.EXPORT,
|
||||
':common': MochiKit.Format.EXPORT
|
||||
};
|
||||
|
||||
MochiKit.Format.__new__ = function () {
|
||||
// MochiKit.Base.nameFunctions(this);
|
||||
var base = this.NAME + ".";
|
||||
var k, v, o;
|
||||
for (k in this.LOCALE) {
|
||||
o = this.LOCALE[k];
|
||||
if (typeof(o) == "object") {
|
||||
o.repr = function () { return this.NAME; };
|
||||
o.NAME = base + "LOCALE." + k;
|
||||
}
|
||||
}
|
||||
for (k in this) {
|
||||
o = this[k];
|
||||
if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
|
||||
try {
|
||||
o.NAME = base + k;
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.Format.__new__();
|
||||
|
||||
if (typeof(MochiKit.Base) != "undefined") {
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Format);
|
||||
} else {
|
||||
(function (globals, module) {
|
||||
if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined')
|
||||
|| (MochiKit.__export__ === false)) {
|
||||
var all = module.EXPORT_TAGS[":all"];
|
||||
for (var i = 0; i < all.length; i++) {
|
||||
globals[all[i]] = module[all[i]];
|
||||
}
|
||||
}
|
||||
})(this, MochiKit.Format);
|
||||
}
|
|
@ -0,0 +1,851 @@
|
|||
/***
|
||||
|
||||
MochiKit.Iter 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Iter');
|
||||
dojo.require('MochiKit.Base');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Iter depends on MochiKit.Base!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Iter) == 'undefined') {
|
||||
MochiKit.Iter = {};
|
||||
}
|
||||
|
||||
MochiKit.Iter.NAME = "MochiKit.Iter";
|
||||
MochiKit.Iter.VERSION = "1.4";
|
||||
MochiKit.Base.update(MochiKit.Iter, {
|
||||
__repr__: function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
},
|
||||
toString: function () {
|
||||
return this.__repr__();
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.registerIteratorFactory */
|
||||
registerIteratorFactory: function (name, check, iterfactory, /* optional */ override) {
|
||||
MochiKit.Iter.iteratorRegistry.register(name, check, iterfactory, override);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.iter */
|
||||
iter: function (iterable, /* optional */ sentinel) {
|
||||
var self = MochiKit.Iter;
|
||||
if (arguments.length == 2) {
|
||||
return self.takewhile(
|
||||
function (a) { return a != sentinel; },
|
||||
iterable
|
||||
);
|
||||
}
|
||||
if (typeof(iterable.next) == 'function') {
|
||||
return iterable;
|
||||
} else if (typeof(iterable.iter) == 'function') {
|
||||
return iterable.iter();
|
||||
/*
|
||||
} else if (typeof(iterable.__iterator__) == 'function') {
|
||||
//
|
||||
// XXX: We can't support JavaScript 1.7 __iterator__ directly
|
||||
// because of Object.prototype.__iterator__
|
||||
//
|
||||
return iterable.__iterator__();
|
||||
*/
|
||||
}
|
||||
|
||||
try {
|
||||
return self.iteratorRegistry.match(iterable);
|
||||
} catch (e) {
|
||||
var m = MochiKit.Base;
|
||||
if (e == m.NotFound) {
|
||||
e = new TypeError(typeof(iterable) + ": " + m.repr(iterable) + " is not iterable");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.count */
|
||||
count: function (n) {
|
||||
if (!n) {
|
||||
n = 0;
|
||||
}
|
||||
var m = MochiKit.Base;
|
||||
return {
|
||||
repr: function () { return "count(" + n + ")"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: m.counter(n)
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.cycle */
|
||||
cycle: function (p) {
|
||||
var self = MochiKit.Iter;
|
||||
var m = MochiKit.Base;
|
||||
var lst = [];
|
||||
var iterator = self.iter(p);
|
||||
return {
|
||||
repr: function () { return "cycle(...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
try {
|
||||
var rval = iterator.next();
|
||||
lst.push(rval);
|
||||
return rval;
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
if (lst.length === 0) {
|
||||
this.next = function () {
|
||||
throw self.StopIteration;
|
||||
};
|
||||
} else {
|
||||
var i = -1;
|
||||
this.next = function () {
|
||||
i = (i + 1) % lst.length;
|
||||
return lst[i];
|
||||
};
|
||||
}
|
||||
return this.next();
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.repeat */
|
||||
repeat: function (elem, /* optional */n) {
|
||||
var m = MochiKit.Base;
|
||||
if (typeof(n) == 'undefined') {
|
||||
return {
|
||||
repr: function () {
|
||||
return "repeat(" + m.repr(elem) + ")";
|
||||
},
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
return elem;
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
repr: function () {
|
||||
return "repeat(" + m.repr(elem) + ", " + n + ")";
|
||||
},
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
if (n <= 0) {
|
||||
throw MochiKit.Iter.StopIteration;
|
||||
}
|
||||
n -= 1;
|
||||
return elem;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.next */
|
||||
next: function (iterator) {
|
||||
return iterator.next();
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.izip */
|
||||
izip: function (p, q/*, ...*/) {
|
||||
var m = MochiKit.Base;
|
||||
var self = MochiKit.Iter;
|
||||
var next = self.next;
|
||||
var iterables = m.map(self.iter, arguments);
|
||||
return {
|
||||
repr: function () { return "izip(...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () { return m.map(next, iterables); }
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.ifilter */
|
||||
ifilter: function (pred, seq) {
|
||||
var m = MochiKit.Base;
|
||||
seq = MochiKit.Iter.iter(seq);
|
||||
if (pred === null) {
|
||||
pred = m.operator.truth;
|
||||
}
|
||||
return {
|
||||
repr: function () { return "ifilter(...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
while (true) {
|
||||
var rval = seq.next();
|
||||
if (pred(rval)) {
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
// mozilla warnings aren't too bright
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.ifilterfalse */
|
||||
ifilterfalse: function (pred, seq) {
|
||||
var m = MochiKit.Base;
|
||||
seq = MochiKit.Iter.iter(seq);
|
||||
if (pred === null) {
|
||||
pred = m.operator.truth;
|
||||
}
|
||||
return {
|
||||
repr: function () { return "ifilterfalse(...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
while (true) {
|
||||
var rval = seq.next();
|
||||
if (!pred(rval)) {
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
// mozilla warnings aren't too bright
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.islice */
|
||||
islice: function (seq/*, [start,] stop[, step] */) {
|
||||
var self = MochiKit.Iter;
|
||||
var m = MochiKit.Base;
|
||||
seq = self.iter(seq);
|
||||
var start = 0;
|
||||
var stop = 0;
|
||||
var step = 1;
|
||||
var i = -1;
|
||||
if (arguments.length == 2) {
|
||||
stop = arguments[1];
|
||||
} else if (arguments.length == 3) {
|
||||
start = arguments[1];
|
||||
stop = arguments[2];
|
||||
} else {
|
||||
start = arguments[1];
|
||||
stop = arguments[2];
|
||||
step = arguments[3];
|
||||
}
|
||||
return {
|
||||
repr: function () {
|
||||
return "islice(" + ["...", start, stop, step].join(", ") + ")";
|
||||
},
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
var rval;
|
||||
while (i < start) {
|
||||
rval = seq.next();
|
||||
i++;
|
||||
}
|
||||
if (start >= stop) {
|
||||
throw self.StopIteration;
|
||||
}
|
||||
start += step;
|
||||
return rval;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.imap */
|
||||
imap: function (fun, p, q/*, ...*/) {
|
||||
var m = MochiKit.Base;
|
||||
var self = MochiKit.Iter;
|
||||
var iterables = m.map(self.iter, m.extend(null, arguments, 1));
|
||||
var map = m.map;
|
||||
var next = self.next;
|
||||
return {
|
||||
repr: function () { return "imap(...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
return fun.apply(this, map(next, iterables));
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.applymap */
|
||||
applymap: function (fun, seq, self) {
|
||||
seq = MochiKit.Iter.iter(seq);
|
||||
var m = MochiKit.Base;
|
||||
return {
|
||||
repr: function () { return "applymap(...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
return fun.apply(self, seq.next());
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.chain */
|
||||
chain: function (p, q/*, ...*/) {
|
||||
// dumb fast path
|
||||
var self = MochiKit.Iter;
|
||||
var m = MochiKit.Base;
|
||||
if (arguments.length == 1) {
|
||||
return self.iter(arguments[0]);
|
||||
}
|
||||
var argiter = m.map(self.iter, arguments);
|
||||
return {
|
||||
repr: function () { return "chain(...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
while (argiter.length > 1) {
|
||||
try {
|
||||
return argiter[0].next();
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
argiter.shift();
|
||||
}
|
||||
}
|
||||
if (argiter.length == 1) {
|
||||
// optimize last element
|
||||
var arg = argiter.shift();
|
||||
this.next = m.bind("next", arg);
|
||||
return this.next();
|
||||
}
|
||||
throw self.StopIteration;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.takewhile */
|
||||
takewhile: function (pred, seq) {
|
||||
var self = MochiKit.Iter;
|
||||
seq = self.iter(seq);
|
||||
return {
|
||||
repr: function () { return "takewhile(...)"; },
|
||||
toString: MochiKit.Base.forwardCall("repr"),
|
||||
next: function () {
|
||||
var rval = seq.next();
|
||||
if (!pred(rval)) {
|
||||
this.next = function () {
|
||||
throw self.StopIteration;
|
||||
};
|
||||
this.next();
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.dropwhile */
|
||||
dropwhile: function (pred, seq) {
|
||||
seq = MochiKit.Iter.iter(seq);
|
||||
var m = MochiKit.Base;
|
||||
var bind = m.bind;
|
||||
return {
|
||||
"repr": function () { return "dropwhile(...)"; },
|
||||
"toString": m.forwardCall("repr"),
|
||||
"next": function () {
|
||||
while (true) {
|
||||
var rval = seq.next();
|
||||
if (!pred(rval)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.next = bind("next", seq);
|
||||
return rval;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
_tee: function (ident, sync, iterable) {
|
||||
sync.pos[ident] = -1;
|
||||
var m = MochiKit.Base;
|
||||
var listMin = m.listMin;
|
||||
return {
|
||||
repr: function () { return "tee(" + ident + ", ...)"; },
|
||||
toString: m.forwardCall("repr"),
|
||||
next: function () {
|
||||
var rval;
|
||||
var i = sync.pos[ident];
|
||||
|
||||
if (i == sync.max) {
|
||||
rval = iterable.next();
|
||||
sync.deque.push(rval);
|
||||
sync.max += 1;
|
||||
sync.pos[ident] += 1;
|
||||
} else {
|
||||
rval = sync.deque[i - sync.min];
|
||||
sync.pos[ident] += 1;
|
||||
if (i == sync.min && listMin(sync.pos) != sync.min) {
|
||||
sync.min += 1;
|
||||
sync.deque.shift();
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.tee */
|
||||
tee: function (iterable, n/* = 2 */) {
|
||||
var rval = [];
|
||||
var sync = {
|
||||
"pos": [],
|
||||
"deque": [],
|
||||
"max": -1,
|
||||
"min": -1
|
||||
};
|
||||
if (arguments.length == 1 || typeof(n) == "undefined" || n === null) {
|
||||
n = 2;
|
||||
}
|
||||
var self = MochiKit.Iter;
|
||||
iterable = self.iter(iterable);
|
||||
var _tee = self._tee;
|
||||
for (var i = 0; i < n; i++) {
|
||||
rval.push(_tee(i, sync, iterable));
|
||||
}
|
||||
return rval;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.list */
|
||||
list: function (iterable) {
|
||||
// Fast-path for Array and Array-like
|
||||
var rval;
|
||||
if (iterable instanceof Array) {
|
||||
return iterable.slice();
|
||||
}
|
||||
// this is necessary to avoid a Safari crash
|
||||
if (typeof(iterable) == "function" &&
|
||||
!(iterable instanceof Function) &&
|
||||
typeof(iterable.length) == 'number') {
|
||||
rval = [];
|
||||
for (var i = 0; i < iterable.length; i++) {
|
||||
rval.push(iterable[i]);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
var self = MochiKit.Iter;
|
||||
iterable = self.iter(iterable);
|
||||
var rval = [];
|
||||
try {
|
||||
while (true) {
|
||||
rval.push(iterable.next());
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
// mozilla warnings aren't too bright
|
||||
return undefined;
|
||||
},
|
||||
|
||||
|
||||
/** @id MochiKit.Iter.reduce */
|
||||
reduce: function (fn, iterable, /* optional */initial) {
|
||||
var i = 0;
|
||||
var x = initial;
|
||||
var self = MochiKit.Iter;
|
||||
iterable = self.iter(iterable);
|
||||
if (arguments.length < 3) {
|
||||
try {
|
||||
x = iterable.next();
|
||||
} catch (e) {
|
||||
if (e == self.StopIteration) {
|
||||
e = new TypeError("reduce() of empty sequence with no initial value");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
try {
|
||||
while (true) {
|
||||
x = fn(x, iterable.next());
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.range */
|
||||
range: function (/* [start,] stop[, step] */) {
|
||||
var start = 0;
|
||||
var stop = 0;
|
||||
var step = 1;
|
||||
if (arguments.length == 1) {
|
||||
stop = arguments[0];
|
||||
} else if (arguments.length == 2) {
|
||||
start = arguments[0];
|
||||
stop = arguments[1];
|
||||
} else if (arguments.length == 3) {
|
||||
start = arguments[0];
|
||||
stop = arguments[1];
|
||||
step = arguments[2];
|
||||
} else {
|
||||
throw new TypeError("range() takes 1, 2, or 3 arguments!");
|
||||
}
|
||||
if (step === 0) {
|
||||
throw new TypeError("range() step must not be 0");
|
||||
}
|
||||
return {
|
||||
next: function () {
|
||||
if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
|
||||
throw MochiKit.Iter.StopIteration;
|
||||
}
|
||||
var rval = start;
|
||||
start += step;
|
||||
return rval;
|
||||
},
|
||||
repr: function () {
|
||||
return "range(" + [start, stop, step].join(", ") + ")";
|
||||
},
|
||||
toString: MochiKit.Base.forwardCall("repr")
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.sum */
|
||||
sum: function (iterable, start/* = 0 */) {
|
||||
if (typeof(start) == "undefined" || start === null) {
|
||||
start = 0;
|
||||
}
|
||||
var x = start;
|
||||
var self = MochiKit.Iter;
|
||||
iterable = self.iter(iterable);
|
||||
try {
|
||||
while (true) {
|
||||
x += iterable.next();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.exhaust */
|
||||
exhaust: function (iterable) {
|
||||
var self = MochiKit.Iter;
|
||||
iterable = self.iter(iterable);
|
||||
try {
|
||||
while (true) {
|
||||
iterable.next();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.forEach */
|
||||
forEach: function (iterable, func, /* optional */self) {
|
||||
var m = MochiKit.Base;
|
||||
if (arguments.length > 2) {
|
||||
func = m.bind(func, self);
|
||||
}
|
||||
// fast path for array
|
||||
if (m.isArrayLike(iterable)) {
|
||||
try {
|
||||
for (var i = 0; i < iterable.length; i++) {
|
||||
func(iterable[i]);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != MochiKit.Iter.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self = MochiKit.Iter;
|
||||
self.exhaust(self.imap(func, iterable));
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.every */
|
||||
every: function (iterable, func) {
|
||||
var self = MochiKit.Iter;
|
||||
try {
|
||||
self.ifilterfalse(func, iterable).next();
|
||||
return false;
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.sorted */
|
||||
sorted: function (iterable, /* optional */cmp) {
|
||||
var rval = MochiKit.Iter.list(iterable);
|
||||
if (arguments.length == 1) {
|
||||
cmp = MochiKit.Base.compare;
|
||||
}
|
||||
rval.sort(cmp);
|
||||
return rval;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.reversed */
|
||||
reversed: function (iterable) {
|
||||
var rval = MochiKit.Iter.list(iterable);
|
||||
rval.reverse();
|
||||
return rval;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.some */
|
||||
some: function (iterable, func) {
|
||||
var self = MochiKit.Iter;
|
||||
try {
|
||||
self.ifilter(func, iterable).next();
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.iextend */
|
||||
iextend: function (lst, iterable) {
|
||||
if (MochiKit.Base.isArrayLike(iterable)) {
|
||||
// fast-path for array-like
|
||||
for (var i = 0; i < iterable.length; i++) {
|
||||
lst.push(iterable[i]);
|
||||
}
|
||||
} else {
|
||||
var self = MochiKit.Iter;
|
||||
iterable = self.iter(iterable);
|
||||
try {
|
||||
while (true) {
|
||||
lst.push(iterable.next());
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != self.StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lst;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.groupby */
|
||||
groupby: function(iterable, /* optional */ keyfunc) {
|
||||
var m = MochiKit.Base;
|
||||
var self = MochiKit.Iter;
|
||||
if (arguments.length < 2) {
|
||||
keyfunc = m.operator.identity;
|
||||
}
|
||||
iterable = self.iter(iterable);
|
||||
|
||||
// shared
|
||||
var pk = undefined;
|
||||
var k = undefined;
|
||||
var v;
|
||||
|
||||
function fetch() {
|
||||
v = iterable.next();
|
||||
k = keyfunc(v);
|
||||
};
|
||||
|
||||
function eat() {
|
||||
var ret = v;
|
||||
v = undefined;
|
||||
return ret;
|
||||
};
|
||||
|
||||
var first = true;
|
||||
var compare = m.compare;
|
||||
return {
|
||||
repr: function () { return "groupby(...)"; },
|
||||
next: function() {
|
||||
// iterator-next
|
||||
|
||||
// iterate until meet next group
|
||||
while (compare(k, pk) === 0) {
|
||||
fetch();
|
||||
if (first) {
|
||||
first = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pk = k;
|
||||
return [k, {
|
||||
next: function() {
|
||||
// subiterator-next
|
||||
if (v == undefined) { // Is there something to eat?
|
||||
fetch();
|
||||
}
|
||||
if (compare(k, pk) !== 0) {
|
||||
throw self.StopIteration;
|
||||
}
|
||||
return eat();
|
||||
}
|
||||
}];
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.groupby_as_array */
|
||||
groupby_as_array: function (iterable, /* optional */ keyfunc) {
|
||||
var m = MochiKit.Base;
|
||||
var self = MochiKit.Iter;
|
||||
if (arguments.length < 2) {
|
||||
keyfunc = m.operator.identity;
|
||||
}
|
||||
|
||||
iterable = self.iter(iterable);
|
||||
var result = [];
|
||||
var first = true;
|
||||
var prev_key;
|
||||
var compare = m.compare;
|
||||
while (true) {
|
||||
try {
|
||||
var value = iterable.next();
|
||||
var key = keyfunc(value);
|
||||
} catch (e) {
|
||||
if (e == self.StopIteration) {
|
||||
break;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
if (first || compare(key, prev_key) !== 0) {
|
||||
var values = [];
|
||||
result.push([key, values]);
|
||||
}
|
||||
values.push(value);
|
||||
first = false;
|
||||
prev_key = key;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.arrayLikeIter */
|
||||
arrayLikeIter: function (iterable) {
|
||||
var i = 0;
|
||||
return {
|
||||
repr: function () { return "arrayLikeIter(...)"; },
|
||||
toString: MochiKit.Base.forwardCall("repr"),
|
||||
next: function () {
|
||||
if (i >= iterable.length) {
|
||||
throw MochiKit.Iter.StopIteration;
|
||||
}
|
||||
return iterable[i++];
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.hasIterateNext */
|
||||
hasIterateNext: function (iterable) {
|
||||
return (iterable && typeof(iterable.iterateNext) == "function");
|
||||
},
|
||||
|
||||
/** @id MochiKit.Iter.iterateNextIter */
|
||||
iterateNextIter: function (iterable) {
|
||||
return {
|
||||
repr: function () { return "iterateNextIter(...)"; },
|
||||
toString: MochiKit.Base.forwardCall("repr"),
|
||||
next: function () {
|
||||
var rval = iterable.iterateNext();
|
||||
if (rval === null || rval === undefined) {
|
||||
throw MochiKit.Iter.StopIteration;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
MochiKit.Iter.EXPORT_OK = [
|
||||
"iteratorRegistry",
|
||||
"arrayLikeIter",
|
||||
"hasIterateNext",
|
||||
"iterateNextIter",
|
||||
];
|
||||
|
||||
MochiKit.Iter.EXPORT = [
|
||||
"StopIteration",
|
||||
"registerIteratorFactory",
|
||||
"iter",
|
||||
"count",
|
||||
"cycle",
|
||||
"repeat",
|
||||
"next",
|
||||
"izip",
|
||||
"ifilter",
|
||||
"ifilterfalse",
|
||||
"islice",
|
||||
"imap",
|
||||
"applymap",
|
||||
"chain",
|
||||
"takewhile",
|
||||
"dropwhile",
|
||||
"tee",
|
||||
"list",
|
||||
"reduce",
|
||||
"range",
|
||||
"sum",
|
||||
"exhaust",
|
||||
"forEach",
|
||||
"every",
|
||||
"sorted",
|
||||
"reversed",
|
||||
"some",
|
||||
"iextend",
|
||||
"groupby",
|
||||
"groupby_as_array"
|
||||
];
|
||||
|
||||
MochiKit.Iter.__new__ = function () {
|
||||
var m = MochiKit.Base;
|
||||
// Re-use StopIteration if exists (e.g. SpiderMonkey)
|
||||
if (typeof(StopIteration) != "undefined") {
|
||||
this.StopIteration = StopIteration;
|
||||
} else {
|
||||
/** @id MochiKit.Iter.StopIteration */
|
||||
this.StopIteration = new m.NamedError("StopIteration");
|
||||
}
|
||||
this.iteratorRegistry = new m.AdapterRegistry();
|
||||
// Register the iterator factory for arrays
|
||||
this.registerIteratorFactory(
|
||||
"arrayLike",
|
||||
m.isArrayLike,
|
||||
this.arrayLikeIter
|
||||
);
|
||||
|
||||
this.registerIteratorFactory(
|
||||
"iterateNext",
|
||||
this.hasIterateNext,
|
||||
this.iterateNextIter
|
||||
);
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
|
||||
};
|
||||
|
||||
MochiKit.Iter.__new__();
|
||||
|
||||
//
|
||||
// XXX: Internet Explorer blows
|
||||
//
|
||||
if (MochiKit.__export__) {
|
||||
reduce = MochiKit.Iter.reduce;
|
||||
}
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Iter);
|
|
@ -0,0 +1,321 @@
|
|||
/***
|
||||
|
||||
MochiKit.Logging 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Logging');
|
||||
dojo.require('MochiKit.Base');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Logging depends on MochiKit.Base!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Logging) == 'undefined') {
|
||||
MochiKit.Logging = {};
|
||||
}
|
||||
|
||||
MochiKit.Logging.NAME = "MochiKit.Logging";
|
||||
MochiKit.Logging.VERSION = "1.4";
|
||||
MochiKit.Logging.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
|
||||
MochiKit.Logging.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
|
||||
MochiKit.Logging.EXPORT = [
|
||||
"LogLevel",
|
||||
"LogMessage",
|
||||
"Logger",
|
||||
"alertListener",
|
||||
"logger",
|
||||
"log",
|
||||
"logError",
|
||||
"logDebug",
|
||||
"logFatal",
|
||||
"logWarning"
|
||||
];
|
||||
|
||||
|
||||
MochiKit.Logging.EXPORT_OK = [
|
||||
"logLevelAtLeast",
|
||||
"isLogMessage",
|
||||
"compareLogMessage"
|
||||
];
|
||||
|
||||
|
||||
/** @id MochiKit.Logging.LogMessage */
|
||||
MochiKit.Logging.LogMessage = function (num, level, info) {
|
||||
this.num = num;
|
||||
this.level = level;
|
||||
this.info = info;
|
||||
this.timestamp = new Date();
|
||||
};
|
||||
|
||||
MochiKit.Logging.LogMessage.prototype = {
|
||||
/** @id MochiKit.Logging.LogMessage.prototype.repr */
|
||||
repr: function () {
|
||||
var m = MochiKit.Base;
|
||||
return 'LogMessage(' +
|
||||
m.map(
|
||||
m.repr,
|
||||
[this.num, this.level, this.info]
|
||||
).join(', ') + ')';
|
||||
},
|
||||
/** @id MochiKit.Logging.LogMessage.prototype.toString */
|
||||
toString: MochiKit.Base.forwardCall("repr")
|
||||
};
|
||||
|
||||
MochiKit.Base.update(MochiKit.Logging, {
|
||||
/** @id MochiKit.Logging.logLevelAtLeast */
|
||||
logLevelAtLeast: function (minLevel) {
|
||||
var self = MochiKit.Logging;
|
||||
if (typeof(minLevel) == 'string') {
|
||||
minLevel = self.LogLevel[minLevel];
|
||||
}
|
||||
return function (msg) {
|
||||
var msgLevel = msg.level;
|
||||
if (typeof(msgLevel) == 'string') {
|
||||
msgLevel = self.LogLevel[msgLevel];
|
||||
}
|
||||
return msgLevel >= minLevel;
|
||||
};
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.isLogMessage */
|
||||
isLogMessage: function (/* ... */) {
|
||||
var LogMessage = MochiKit.Logging.LogMessage;
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
if (!(arguments[i] instanceof LogMessage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.compareLogMessage */
|
||||
compareLogMessage: function (a, b) {
|
||||
return MochiKit.Base.compare([a.level, a.info], [b.level, b.info]);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.alertListener */
|
||||
alertListener: function (msg) {
|
||||
alert(
|
||||
"num: " + msg.num +
|
||||
"\nlevel: " + msg.level +
|
||||
"\ninfo: " + msg.info.join(" ")
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/** @id MochiKit.Logging.Logger */
|
||||
MochiKit.Logging.Logger = function (/* optional */maxSize) {
|
||||
this.counter = 0;
|
||||
if (typeof(maxSize) == 'undefined' || maxSize === null) {
|
||||
maxSize = -1;
|
||||
}
|
||||
this.maxSize = maxSize;
|
||||
this._messages = [];
|
||||
this.listeners = {};
|
||||
this.useNativeConsole = false;
|
||||
};
|
||||
|
||||
MochiKit.Logging.Logger.prototype = {
|
||||
/** @id MochiKit.Logging.Logger.prototype.clear */
|
||||
clear: function () {
|
||||
this._messages.splice(0, this._messages.length);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.logToConsole */
|
||||
logToConsole: function (msg) {
|
||||
if (typeof(window) != "undefined" && window.console
|
||||
&& window.console.log) {
|
||||
// Safari and FireBug 0.4
|
||||
// Percent replacement is a workaround for cute Safari crashing bug
|
||||
window.console.log(msg.replace(/%/g, '\uFF05'));
|
||||
} else if (typeof(opera) != "undefined" && opera.postError) {
|
||||
// Opera
|
||||
opera.postError(msg);
|
||||
} else if (typeof(printfire) == "function") {
|
||||
// FireBug 0.3 and earlier
|
||||
printfire(msg);
|
||||
} else if (typeof(Debug) != "undefined" && Debug.writeln) {
|
||||
// IE Web Development Helper (?)
|
||||
// http://www.nikhilk.net/Entry.aspx?id=93
|
||||
Debug.writeln(msg);
|
||||
} else if (typeof(debug) != "undefined" && debug.trace) {
|
||||
// Atlas framework (?)
|
||||
// http://www.nikhilk.net/Entry.aspx?id=93
|
||||
debug.trace(msg);
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.dispatchListeners */
|
||||
dispatchListeners: function (msg) {
|
||||
for (var k in this.listeners) {
|
||||
var pair = this.listeners[k];
|
||||
if (pair.ident != k || (pair[0] && !pair[0](msg))) {
|
||||
continue;
|
||||
}
|
||||
pair[1](msg);
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.addListener */
|
||||
addListener: function (ident, filter, listener) {
|
||||
if (typeof(filter) == 'string') {
|
||||
filter = MochiKit.Logging.logLevelAtLeast(filter);
|
||||
}
|
||||
var entry = [filter, listener];
|
||||
entry.ident = ident;
|
||||
this.listeners[ident] = entry;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.removeListener */
|
||||
removeListener: function (ident) {
|
||||
delete this.listeners[ident];
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.baseLog */
|
||||
baseLog: function (level, message/*, ...*/) {
|
||||
var msg = new MochiKit.Logging.LogMessage(
|
||||
this.counter,
|
||||
level,
|
||||
MochiKit.Base.extend(null, arguments, 1)
|
||||
);
|
||||
this._messages.push(msg);
|
||||
this.dispatchListeners(msg);
|
||||
if (this.useNativeConsole) {
|
||||
this.logToConsole(msg.level + ": " + msg.info.join(" "));
|
||||
}
|
||||
this.counter += 1;
|
||||
while (this.maxSize >= 0 && this._messages.length > this.maxSize) {
|
||||
this._messages.shift();
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.getMessages */
|
||||
getMessages: function (howMany) {
|
||||
var firstMsg = 0;
|
||||
if (!(typeof(howMany) == 'undefined' || howMany === null)) {
|
||||
firstMsg = Math.max(0, this._messages.length - howMany);
|
||||
}
|
||||
return this._messages.slice(firstMsg);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.getMessageText */
|
||||
getMessageText: function (howMany) {
|
||||
if (typeof(howMany) == 'undefined' || howMany === null) {
|
||||
howMany = 30;
|
||||
}
|
||||
var messages = this.getMessages(howMany);
|
||||
if (messages.length) {
|
||||
var lst = map(function (m) {
|
||||
return '\n [' + m.num + '] ' + m.level + ': ' + m.info.join(' ');
|
||||
}, messages);
|
||||
lst.unshift('LAST ' + messages.length + ' MESSAGES:');
|
||||
return lst.join('');
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/** @id MochiKit.Logging.Logger.prototype.debuggingBookmarklet */
|
||||
debuggingBookmarklet: function (inline) {
|
||||
if (typeof(MochiKit.LoggingPane) == "undefined") {
|
||||
alert(this.getMessageText());
|
||||
} else {
|
||||
MochiKit.LoggingPane.createLoggingPane(inline || false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.Logging.__new__ = function () {
|
||||
this.LogLevel = {
|
||||
ERROR: 40,
|
||||
FATAL: 50,
|
||||
WARNING: 30,
|
||||
INFO: 20,
|
||||
DEBUG: 10
|
||||
};
|
||||
|
||||
var m = MochiKit.Base;
|
||||
m.registerComparator("LogMessage",
|
||||
this.isLogMessage,
|
||||
this.compareLogMessage
|
||||
);
|
||||
|
||||
var partial = m.partial;
|
||||
|
||||
var Logger = this.Logger;
|
||||
var baseLog = Logger.prototype.baseLog;
|
||||
m.update(this.Logger.prototype, {
|
||||
debug: partial(baseLog, 'DEBUG'),
|
||||
log: partial(baseLog, 'INFO'),
|
||||
error: partial(baseLog, 'ERROR'),
|
||||
fatal: partial(baseLog, 'FATAL'),
|
||||
warning: partial(baseLog, 'WARNING')
|
||||
});
|
||||
|
||||
// indirectly find logger so it can be replaced
|
||||
var self = this;
|
||||
var connectLog = function (name) {
|
||||
return function () {
|
||||
self.logger[name].apply(self.logger, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
/** @id MochiKit.Logging.log */
|
||||
this.log = connectLog('log');
|
||||
/** @id MochiKit.Logging.logError */
|
||||
this.logError = connectLog('error');
|
||||
/** @id MochiKit.Logging.logDebug */
|
||||
this.logDebug = connectLog('debug');
|
||||
/** @id MochiKit.Logging.logFatal */
|
||||
this.logFatal = connectLog('fatal');
|
||||
/** @id MochiKit.Logging.logWarning */
|
||||
this.logWarning = connectLog('warning');
|
||||
this.logger = new Logger();
|
||||
this.logger.useNativeConsole = true;
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
|
||||
};
|
||||
|
||||
if (typeof(printfire) == "undefined" &&
|
||||
typeof(document) != "undefined" && document.createEvent &&
|
||||
typeof(dispatchEvent) != "undefined") {
|
||||
// FireBug really should be less lame about this global function
|
||||
printfire = function () {
|
||||
printfire.args = arguments;
|
||||
var ev = document.createEvent("Events");
|
||||
ev.initEvent("printfire", false, true);
|
||||
dispatchEvent(ev);
|
||||
};
|
||||
}
|
||||
|
||||
MochiKit.Logging.__new__();
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Logging);
|
|
@ -0,0 +1,374 @@
|
|||
/***
|
||||
|
||||
MochiKit.LoggingPane 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.LoggingPane');
|
||||
dojo.require('MochiKit.Logging');
|
||||
dojo.require('MochiKit.Base');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Logging", []);
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined' || typeof(MochiKit.Logging) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.LoggingPane depends on MochiKit.Base and MochiKit.Logging!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.LoggingPane) == 'undefined') {
|
||||
MochiKit.LoggingPane = {};
|
||||
}
|
||||
|
||||
MochiKit.LoggingPane.NAME = "MochiKit.LoggingPane";
|
||||
MochiKit.LoggingPane.VERSION = "1.4";
|
||||
MochiKit.LoggingPane.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
|
||||
MochiKit.LoggingPane.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.createLoggingPane */
|
||||
MochiKit.LoggingPane.createLoggingPane = function (inline/* = false */) {
|
||||
var m = MochiKit.LoggingPane;
|
||||
inline = !(!inline);
|
||||
if (m._loggingPane && m._loggingPane.inline != inline) {
|
||||
m._loggingPane.closePane();
|
||||
m._loggingPane = null;
|
||||
}
|
||||
if (!m._loggingPane || m._loggingPane.closed) {
|
||||
m._loggingPane = new m.LoggingPane(inline, MochiKit.Logging.logger);
|
||||
}
|
||||
return m._loggingPane;
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.LoggingPane */
|
||||
MochiKit.LoggingPane.LoggingPane = function (inline/* = false */, logger/* = MochiKit.Logging.logger */) {
|
||||
|
||||
/* Use a div if inline, pop up a window if not */
|
||||
/* Create the elements */
|
||||
if (typeof(logger) == "undefined" || logger === null) {
|
||||
logger = MochiKit.Logging.logger;
|
||||
}
|
||||
this.logger = logger;
|
||||
var update = MochiKit.Base.update;
|
||||
var updatetree = MochiKit.Base.updatetree;
|
||||
var bind = MochiKit.Base.bind;
|
||||
var clone = MochiKit.Base.clone;
|
||||
var win = window;
|
||||
var uid = "_MochiKit_LoggingPane";
|
||||
if (typeof(MochiKit.DOM) != "undefined") {
|
||||
win = MochiKit.DOM.currentWindow();
|
||||
}
|
||||
if (!inline) {
|
||||
// name the popup with the base URL for uniqueness
|
||||
var url = win.location.href.split("?")[0].replace(/[#:\/.><&-]/g, "_");
|
||||
var name = uid + "_" + url;
|
||||
var nwin = win.open("", name, "dependent,resizable,height=200");
|
||||
if (!nwin) {
|
||||
alert("Not able to open debugging window due to pop-up blocking.");
|
||||
return undefined;
|
||||
}
|
||||
nwin.document.write(
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
|
||||
+ '"http://www.w3.org/TR/html4/loose.dtd">'
|
||||
+ '<html><head><title>[MochiKit.LoggingPane]</title></head>'
|
||||
+ '<body></body></html>'
|
||||
);
|
||||
nwin.document.close();
|
||||
nwin.document.title += ' ' + win.document.title;
|
||||
win = nwin;
|
||||
}
|
||||
var doc = win.document;
|
||||
this.doc = doc;
|
||||
|
||||
// Connect to the debug pane if it already exists (i.e. in a window orphaned by the page being refreshed)
|
||||
var debugPane = doc.getElementById(uid);
|
||||
var existing_pane = !!debugPane;
|
||||
if (debugPane && typeof(debugPane.loggingPane) != "undefined") {
|
||||
debugPane.loggingPane.logger = this.logger;
|
||||
debugPane.loggingPane.buildAndApplyFilter();
|
||||
return debugPane.loggingPane;
|
||||
}
|
||||
|
||||
if (existing_pane) {
|
||||
// clear any existing contents
|
||||
var child;
|
||||
while ((child = debugPane.firstChild)) {
|
||||
debugPane.removeChild(child);
|
||||
}
|
||||
} else {
|
||||
debugPane = doc.createElement("div");
|
||||
debugPane.id = uid;
|
||||
}
|
||||
debugPane.loggingPane = this;
|
||||
var levelFilterField = doc.createElement("input");
|
||||
var infoFilterField = doc.createElement("input");
|
||||
var filterButton = doc.createElement("button");
|
||||
var loadButton = doc.createElement("button");
|
||||
var clearButton = doc.createElement("button");
|
||||
var closeButton = doc.createElement("button");
|
||||
var logPaneArea = doc.createElement("div");
|
||||
var logPane = doc.createElement("div");
|
||||
|
||||
/* Set up the functions */
|
||||
var listenerId = uid + "_Listener";
|
||||
this.colorTable = clone(this.colorTable);
|
||||
var messages = [];
|
||||
var messageFilter = null;
|
||||
|
||||
/** @id MochiKit.LoggingPane.messageLevel */
|
||||
var messageLevel = function (msg) {
|
||||
var level = msg.level;
|
||||
if (typeof(level) == "number") {
|
||||
level = MochiKit.Logging.LogLevel[level];
|
||||
}
|
||||
return level;
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.messageText */
|
||||
var messageText = function (msg) {
|
||||
return msg.info.join(" ");
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.addMessageText */
|
||||
var addMessageText = bind(function (msg) {
|
||||
var level = messageLevel(msg);
|
||||
var text = messageText(msg);
|
||||
var c = this.colorTable[level];
|
||||
var p = doc.createElement("span");
|
||||
p.className = "MochiKit-LogMessage MochiKit-LogLevel-" + level;
|
||||
p.style.cssText = "margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: " + c;
|
||||
p.appendChild(doc.createTextNode(level + ": " + text));
|
||||
logPane.appendChild(p);
|
||||
logPane.appendChild(doc.createElement("br"));
|
||||
if (logPaneArea.offsetHeight > logPaneArea.scrollHeight) {
|
||||
logPaneArea.scrollTop = 0;
|
||||
} else {
|
||||
logPaneArea.scrollTop = logPaneArea.scrollHeight;
|
||||
}
|
||||
}, this);
|
||||
|
||||
/** @id MochiKit.LoggingPane.addMessage */
|
||||
var addMessage = function (msg) {
|
||||
messages[messages.length] = msg;
|
||||
addMessageText(msg);
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.buildMessageFilter */
|
||||
var buildMessageFilter = function () {
|
||||
var levelre, infore;
|
||||
try {
|
||||
/* Catch any exceptions that might arise due to invalid regexes */
|
||||
levelre = new RegExp(levelFilterField.value);
|
||||
infore = new RegExp(infoFilterField.value);
|
||||
} catch(e) {
|
||||
/* If there was an error with the regexes, do no filtering */
|
||||
logDebug("Error in filter regex: " + e.message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return function (msg) {
|
||||
return (
|
||||
levelre.test(messageLevel(msg)) &&
|
||||
infore.test(messageText(msg))
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.clearMessagePane */
|
||||
var clearMessagePane = function () {
|
||||
while (logPane.firstChild) {
|
||||
logPane.removeChild(logPane.firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.clearMessages */
|
||||
var clearMessages = function () {
|
||||
messages = [];
|
||||
clearMessagePane();
|
||||
};
|
||||
|
||||
/** @id MochiKit.LoggingPane.closePane */
|
||||
var closePane = bind(function () {
|
||||
if (this.closed) {
|
||||
return;
|
||||
}
|
||||
this.closed = true;
|
||||
if (MochiKit.LoggingPane._loggingPane == this) {
|
||||
MochiKit.LoggingPane._loggingPane = null;
|
||||
}
|
||||
this.logger.removeListener(listenerId);
|
||||
try {
|
||||
try {
|
||||
debugPane.loggingPane = null;
|
||||
} catch(e) { logFatal("Bookmarklet was closed incorrectly."); }
|
||||
if (inline) {
|
||||
debugPane.parentNode.removeChild(debugPane);
|
||||
} else {
|
||||
this.win.close();
|
||||
}
|
||||
} catch(e) {}
|
||||
}, this);
|
||||
|
||||
/** @id MochiKit.LoggingPane.filterMessages */
|
||||
var filterMessages = function () {
|
||||
clearMessagePane();
|
||||
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
var msg = messages[i];
|
||||
if (messageFilter === null || messageFilter(msg)) {
|
||||
addMessageText(msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.buildAndApplyFilter = function () {
|
||||
messageFilter = buildMessageFilter();
|
||||
|
||||
filterMessages();
|
||||
|
||||
this.logger.removeListener(listenerId);
|
||||
this.logger.addListener(listenerId, messageFilter, addMessage);
|
||||
};
|
||||
|
||||
|
||||
/** @id MochiKit.LoggingPane.loadMessages */
|
||||
var loadMessages = bind(function () {
|
||||
messages = this.logger.getMessages();
|
||||
filterMessages();
|
||||
}, this);
|
||||
|
||||
/** @id MochiKit.LoggingPane.filterOnEnter */
|
||||
var filterOnEnter = bind(function (event) {
|
||||
event = event || window.event;
|
||||
key = event.which || event.keyCode;
|
||||
if (key == 13) {
|
||||
this.buildAndApplyFilter();
|
||||
}
|
||||
}, this);
|
||||
|
||||
/* Create the debug pane */
|
||||
var style = "display: block; z-index: 1000; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: " + this.logFont;
|
||||
if (inline) {
|
||||
style += "; height: 10em; border-top: 2px solid black";
|
||||
} else {
|
||||
style += "; height: 100%;";
|
||||
}
|
||||
debugPane.style.cssText = style;
|
||||
|
||||
if (!existing_pane) {
|
||||
doc.body.appendChild(debugPane);
|
||||
}
|
||||
|
||||
/* Create the filter fields */
|
||||
style = {"cssText": "width: 33%; display: inline; font: " + this.logFont};
|
||||
|
||||
updatetree(levelFilterField, {
|
||||
"value": "FATAL|ERROR|WARNING|INFO|DEBUG",
|
||||
"onkeypress": filterOnEnter,
|
||||
"style": style
|
||||
});
|
||||
debugPane.appendChild(levelFilterField);
|
||||
|
||||
updatetree(infoFilterField, {
|
||||
"value": ".*",
|
||||
"onkeypress": filterOnEnter,
|
||||
"style": style
|
||||
});
|
||||
debugPane.appendChild(infoFilterField);
|
||||
|
||||
/* Create the buttons */
|
||||
style = "width: 8%; display:inline; font: " + this.logFont;
|
||||
|
||||
filterButton.appendChild(doc.createTextNode("Filter"));
|
||||
filterButton.onclick = bind("buildAndApplyFilter", this);
|
||||
filterButton.style.cssText = style;
|
||||
debugPane.appendChild(filterButton);
|
||||
|
||||
loadButton.appendChild(doc.createTextNode("Load"));
|
||||
loadButton.onclick = loadMessages;
|
||||
loadButton.style.cssText = style;
|
||||
debugPane.appendChild(loadButton);
|
||||
|
||||
clearButton.appendChild(doc.createTextNode("Clear"));
|
||||
clearButton.onclick = clearMessages;
|
||||
clearButton.style.cssText = style;
|
||||
debugPane.appendChild(clearButton);
|
||||
|
||||
closeButton.appendChild(doc.createTextNode("Close"));
|
||||
closeButton.onclick = closePane;
|
||||
closeButton.style.cssText = style;
|
||||
debugPane.appendChild(closeButton);
|
||||
|
||||
/* Create the logging pane */
|
||||
logPaneArea.style.cssText = "overflow: auto; width: 100%";
|
||||
logPane.style.cssText = "width: 100%; height: " + (inline ? "8em" : "100%");
|
||||
|
||||
logPaneArea.appendChild(logPane);
|
||||
debugPane.appendChild(logPaneArea);
|
||||
|
||||
this.buildAndApplyFilter();
|
||||
loadMessages();
|
||||
|
||||
if (inline) {
|
||||
this.win = undefined;
|
||||
} else {
|
||||
this.win = win;
|
||||
}
|
||||
this.inline = inline;
|
||||
this.closePane = closePane;
|
||||
this.closed = false;
|
||||
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
MochiKit.LoggingPane.LoggingPane.prototype = {
|
||||
"logFont": "8pt Verdana,sans-serif",
|
||||
"colorTable": {
|
||||
"ERROR": "red",
|
||||
"FATAL": "darkred",
|
||||
"WARNING": "blue",
|
||||
"INFO": "black",
|
||||
"DEBUG": "green"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MochiKit.LoggingPane.EXPORT_OK = [
|
||||
"LoggingPane"
|
||||
];
|
||||
|
||||
MochiKit.LoggingPane.EXPORT = [
|
||||
"createLoggingPane"
|
||||
];
|
||||
|
||||
MochiKit.LoggingPane.__new__ = function () {
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": MochiKit.Base.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
MochiKit.Base.nameFunctions(this);
|
||||
|
||||
MochiKit.LoggingPane._loggingPane = null;
|
||||
|
||||
};
|
||||
|
||||
MochiKit.LoggingPane.__new__();
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.LoggingPane);
|
|
@ -0,0 +1,73 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/ajax/mochikit/Mochikit
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
Async.js \
|
||||
Base.js \
|
||||
Color.js \
|
||||
Controls.js \
|
||||
DOM.js \
|
||||
DateTime.js \
|
||||
DragAndDrop.js \
|
||||
Format.js \
|
||||
Iter.js \
|
||||
Logging.js \
|
||||
LoggingPane.js \
|
||||
MochiKit.js \
|
||||
MockDOM.js \
|
||||
Position.js \
|
||||
Selector.js \
|
||||
Signal.js \
|
||||
Sortable.js \
|
||||
Style.js \
|
||||
Test.js \
|
||||
Visual.js \
|
||||
__package__.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
|
@ -0,0 +1,154 @@
|
|||
/***
|
||||
|
||||
MochiKit.MochiKit 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(MochiKit) == 'undefined') {
|
||||
MochiKit = {};
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.MochiKit) == 'undefined') {
|
||||
/** @id MochiKit.MochiKit */
|
||||
MochiKit.MochiKit = {};
|
||||
}
|
||||
|
||||
MochiKit.MochiKit.NAME = "MochiKit.MochiKit";
|
||||
MochiKit.MochiKit.VERSION = "1.4";
|
||||
MochiKit.MochiKit.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
|
||||
/** @id MochiKit.MochiKit.toString */
|
||||
MochiKit.MochiKit.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
/** @id MochiKit.MochiKit.SUBMODULES */
|
||||
MochiKit.MochiKit.SUBMODULES = [
|
||||
"Base",
|
||||
"Iter",
|
||||
"Logging",
|
||||
"DateTime",
|
||||
"Format",
|
||||
"Async",
|
||||
"DOM",
|
||||
"Selector",
|
||||
"Style",
|
||||
"LoggingPane",
|
||||
"Color",
|
||||
"Signal",
|
||||
"Position",
|
||||
"Visual"
|
||||
];
|
||||
|
||||
if (typeof(JSAN) != 'undefined' || typeof(dojo) != 'undefined') {
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.MochiKit');
|
||||
dojo.require("MochiKit.*");
|
||||
}
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
(function (lst) {
|
||||
for (var i = 0; i < lst.length; i++) {
|
||||
JSAN.use("MochiKit." + lst[i], []);
|
||||
}
|
||||
})(MochiKit.MochiKit.SUBMODULES);
|
||||
}
|
||||
(function () {
|
||||
var extend = MochiKit.Base.extend;
|
||||
var self = MochiKit.MochiKit;
|
||||
var modules = self.SUBMODULES;
|
||||
var EXPORT = [];
|
||||
var EXPORT_OK = [];
|
||||
var EXPORT_TAGS = {};
|
||||
var i, k, m, all;
|
||||
for (i = 0; i < modules.length; i++) {
|
||||
m = MochiKit[modules[i]];
|
||||
extend(EXPORT, m.EXPORT);
|
||||
extend(EXPORT_OK, m.EXPORT_OK);
|
||||
for (k in m.EXPORT_TAGS) {
|
||||
EXPORT_TAGS[k] = extend(EXPORT_TAGS[k], m.EXPORT_TAGS[k]);
|
||||
}
|
||||
all = m.EXPORT_TAGS[":all"];
|
||||
if (!all) {
|
||||
all = extend(null, m.EXPORT, m.EXPORT_OK);
|
||||
}
|
||||
var j;
|
||||
for (j = 0; j < all.length; j++) {
|
||||
k = all[j];
|
||||
self[k] = m[k];
|
||||
}
|
||||
}
|
||||
self.EXPORT = EXPORT;
|
||||
self.EXPORT_OK = EXPORT_OK;
|
||||
self.EXPORT_TAGS = EXPORT_TAGS;
|
||||
}());
|
||||
|
||||
} else {
|
||||
if (typeof(MochiKit.__compat__) == 'undefined') {
|
||||
MochiKit.__compat__ = true;
|
||||
}
|
||||
(function () {
|
||||
if (typeof(document) == "undefined") {
|
||||
return;
|
||||
}
|
||||
var scripts = document.getElementsByTagName("script");
|
||||
var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var base = null;
|
||||
var baseElem = null;
|
||||
var allScripts = {};
|
||||
var i;
|
||||
for (i = 0; i < scripts.length; i++) {
|
||||
var src = scripts[i].getAttribute("src");
|
||||
if (!src) {
|
||||
continue;
|
||||
}
|
||||
allScripts[src] = true;
|
||||
if (src.match(/MochiKit.js$/)) {
|
||||
base = src.substring(0, src.lastIndexOf('MochiKit.js'));
|
||||
baseElem = scripts[i];
|
||||
}
|
||||
}
|
||||
if (base === null) {
|
||||
return;
|
||||
}
|
||||
var modules = MochiKit.MochiKit.SUBMODULES;
|
||||
for (var i = 0; i < modules.length; i++) {
|
||||
if (MochiKit[modules[i]]) {
|
||||
continue;
|
||||
}
|
||||
var uri = base + modules[i] + '.js';
|
||||
if (uri in allScripts) {
|
||||
continue;
|
||||
}
|
||||
if (document.documentElement &&
|
||||
document.documentElement.namespaceURI == kXULNSURI) {
|
||||
// XUL
|
||||
var s = document.createElementNS(kXULNSURI, 'script');
|
||||
s.setAttribute("id", "MochiKit_" + base + modules[i]);
|
||||
s.setAttribute("src", uri);
|
||||
s.setAttribute("type", "application/x-javascript");
|
||||
baseElem.parentNode.appendChild(s);
|
||||
} else {
|
||||
// HTML
|
||||
/*
|
||||
DOM can not be used here because Safari does
|
||||
deferred loading of scripts unless they are
|
||||
in the document or inserted with document.write
|
||||
|
||||
This is not XHTML compliant. If you want XHTML
|
||||
compliance then you must use the packed version of MochiKit
|
||||
or include each script individually (basically unroll
|
||||
these document.write calls into your XHTML source)
|
||||
|
||||
*/
|
||||
document.write('<script src="' + uri +
|
||||
'" type="text/javascript"></script>');
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/***
|
||||
|
||||
MochiKit.MockDOM 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(MochiKit) == "undefined") {
|
||||
MochiKit = {};
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.MockDOM) == "undefined") {
|
||||
MochiKit.MockDOM = {};
|
||||
}
|
||||
|
||||
MochiKit.MockDOM.NAME = "MochiKit.MockDOM";
|
||||
MochiKit.MockDOM.VERSION = "1.4";
|
||||
|
||||
MochiKit.MockDOM.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
|
||||
/** @id MochiKit.MockDOM.toString */
|
||||
MochiKit.MockDOM.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
/** @id MochiKit.MockDOM.createDocument */
|
||||
MochiKit.MockDOM.createDocument = function () {
|
||||
var doc = new MochiKit.MockDOM.MockElement("DOCUMENT");
|
||||
doc.body = doc.createElement("BODY");
|
||||
doc.appendChild(doc.body);
|
||||
return doc;
|
||||
};
|
||||
|
||||
/** @id MochiKit.MockDOM.MockElement */
|
||||
MochiKit.MockDOM.MockElement = function (name, data, ownerDocument) {
|
||||
this.tagName = this.nodeName = name.toUpperCase();
|
||||
this.ownerDocument = ownerDocument || null;
|
||||
if (name == "DOCUMENT") {
|
||||
this.nodeType = 9;
|
||||
this.childNodes = [];
|
||||
} else if (typeof(data) == "string") {
|
||||
this.nodeValue = data;
|
||||
this.nodeType = 3;
|
||||
} else {
|
||||
this.nodeType = 1;
|
||||
this.childNodes = [];
|
||||
}
|
||||
if (name.substring(0, 1) == "<") {
|
||||
var nameattr = name.substring(
|
||||
name.indexOf('"') + 1, name.lastIndexOf('"'));
|
||||
name = name.substring(1, name.indexOf(" "));
|
||||
this.tagName = this.nodeName = name.toUpperCase();
|
||||
this.setAttribute("name", nameattr);
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.MockDOM.MockElement.prototype = {
|
||||
/** @id MochiKit.MockDOM.MockElement.prototype.createElement */
|
||||
createElement: function (tagName) {
|
||||
return new MochiKit.MockDOM.MockElement(tagName, null, this.nodeType == 9 ? this : this.ownerDocument);
|
||||
},
|
||||
/** @id MochiKit.MockDOM.MockElement.prototype.createTextNode */
|
||||
createTextNode: function (text) {
|
||||
return new MochiKit.MockDOM.MockElement("text", text, this.nodeType == 9 ? this : this.ownerDocument);
|
||||
},
|
||||
/** @id MochiKit.MockDOM.MockElement.prototype.setAttribute */
|
||||
setAttribute: function (name, value) {
|
||||
this[name] = value;
|
||||
},
|
||||
/** @id MochiKit.MockDOM.MockElement.prototype.getAttribute */
|
||||
getAttribute: function (name) {
|
||||
return this[name];
|
||||
},
|
||||
/** @id MochiKit.MockDOM.MockElement.prototype.appendChild */
|
||||
appendChild: function (child) {
|
||||
this.childNodes.push(child);
|
||||
},
|
||||
/** @id MochiKit.MockDOM.MockElement.prototype.toString */
|
||||
toString: function () {
|
||||
return "MockElement(" + this.tagName + ")";
|
||||
},
|
||||
/** @id MochiKit.MockDOM.MockElement.prototype.getElementsByTagName */
|
||||
getElementsByTagName: function (tagName) {
|
||||
var foundElements = [];
|
||||
MochiKit.Base.nodeWalk(this, function(node){
|
||||
if (tagName == '*' || tagName == node.tagName) {
|
||||
foundElements.push(node);
|
||||
return node.childNodes;
|
||||
}
|
||||
});
|
||||
return foundElements;
|
||||
}
|
||||
};
|
||||
|
||||
/** @id MochiKit.MockDOM.EXPORT_OK */
|
||||
MochiKit.MockDOM.EXPORT_OK = [
|
||||
"mockElement",
|
||||
"createDocument"
|
||||
];
|
||||
|
||||
/** @id MochiKit.MockDOM.EXPORT */
|
||||
MochiKit.MockDOM.EXPORT = [
|
||||
"document"
|
||||
];
|
||||
|
||||
MochiKit.MockDOM.__new__ = function () {
|
||||
this.document = this.createDocument();
|
||||
};
|
||||
|
||||
MochiKit.MockDOM.__new__();
|
|
@ -0,0 +1,258 @@
|
|||
/***
|
||||
|
||||
MochiKit.Position 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005-2006 Bob Ippolito and others. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Position');
|
||||
dojo.require('MochiKit.Base');
|
||||
dojo.require('MochiKit.DOM');
|
||||
dojo.require('MochiKit.Style');
|
||||
}
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use('MochiKit.Base', []);
|
||||
JSAN.use('MochiKit.DOM', []);
|
||||
JSAN.use('MochiKit.Style', []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined' ||
|
||||
typeof(MochiKit.Style) == 'undefined' ||
|
||||
typeof(MochiKit.DOM) == 'undefined') {
|
||||
throw '';
|
||||
}
|
||||
} catch (e) {
|
||||
throw 'MochiKit.Style depends on MochiKit.Base, MochiKit.DOM, and MochiKit.Style!';
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Position) == 'undefined') {
|
||||
MochiKit.Position = {};
|
||||
}
|
||||
|
||||
MochiKit.Position.NAME = 'MochiKit.Position';
|
||||
MochiKit.Position.VERSION = '1.4';
|
||||
MochiKit.Position.__repr__ = function () {
|
||||
return '[' + this.NAME + ' ' + this.VERSION + ']';
|
||||
};
|
||||
MochiKit.Position.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
MochiKit.Position.EXPORT_OK = [];
|
||||
|
||||
MochiKit.Position.EXPORT = [
|
||||
];
|
||||
|
||||
|
||||
MochiKit.Base.update(MochiKit.Position, {
|
||||
// set to true if needed, warning: firefox performance problems
|
||||
// NOT neeeded for page scrolling, only if draggable contained in
|
||||
// scrollable elements
|
||||
includeScrollOffsets: false,
|
||||
|
||||
/** @id MochiKit.Position.prepare */
|
||||
prepare: function () {
|
||||
var deltaX = window.pageXOffset
|
||||
|| document.documentElement.scrollLeft
|
||||
|| document.body.scrollLeft
|
||||
|| 0;
|
||||
var deltaY = window.pageYOffset
|
||||
|| document.documentElement.scrollTop
|
||||
|| document.body.scrollTop
|
||||
|| 0;
|
||||
this.windowOffset = new MochiKit.Style.Coordinates(deltaX, deltaY);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.cumulativeOffset */
|
||||
cumulativeOffset: function (element) {
|
||||
var valueT = 0;
|
||||
var valueL = 0;
|
||||
do {
|
||||
valueT += element.offsetTop || 0;
|
||||
valueL += element.offsetLeft || 0;
|
||||
element = element.offsetParent;
|
||||
} while (element);
|
||||
return new MochiKit.Style.Coordinates(valueL, valueT);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.realOffset */
|
||||
realOffset: function (element) {
|
||||
var valueT = 0;
|
||||
var valueL = 0;
|
||||
do {
|
||||
valueT += element.scrollTop || 0;
|
||||
valueL += element.scrollLeft || 0;
|
||||
element = element.parentNode;
|
||||
} while (element);
|
||||
return new MochiKit.Style.Coordinates(valueL, valueT);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.within */
|
||||
within: function (element, x, y) {
|
||||
if (this.includeScrollOffsets) {
|
||||
return this.withinIncludingScrolloffsets(element, x, y);
|
||||
}
|
||||
this.xcomp = x;
|
||||
this.ycomp = y;
|
||||
this.offset = this.cumulativeOffset(element);
|
||||
if (element.style.position == "fixed") {
|
||||
this.offset.x += this.windowOffset.x;
|
||||
this.offset.y += this.windowOffset.y;
|
||||
}
|
||||
|
||||
return (y >= this.offset.y &&
|
||||
y < this.offset.y + element.offsetHeight &&
|
||||
x >= this.offset.x &&
|
||||
x < this.offset.x + element.offsetWidth);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.withinIncludingScrolloffsets */
|
||||
withinIncludingScrolloffsets: function (element, x, y) {
|
||||
var offsetcache = this.realOffset(element);
|
||||
|
||||
this.xcomp = x + offsetcache.x - this.windowOffset.x;
|
||||
this.ycomp = y + offsetcache.y - this.windowOffset.y;
|
||||
this.offset = this.cumulativeOffset(element);
|
||||
|
||||
return (this.ycomp >= this.offset.y &&
|
||||
this.ycomp < this.offset.y + element.offsetHeight &&
|
||||
this.xcomp >= this.offset.x &&
|
||||
this.xcomp < this.offset.x + element.offsetWidth);
|
||||
},
|
||||
|
||||
// within must be called directly before
|
||||
/** @id MochiKit.Position.overlap */
|
||||
overlap: function (mode, element) {
|
||||
if (!mode) {
|
||||
return 0;
|
||||
}
|
||||
if (mode == 'vertical') {
|
||||
return ((this.offset.y + element.offsetHeight) - this.ycomp) /
|
||||
element.offsetHeight;
|
||||
}
|
||||
if (mode == 'horizontal') {
|
||||
return ((this.offset.x + element.offsetWidth) - this.xcomp) /
|
||||
element.offsetWidth;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.absolutize */
|
||||
absolutize: function (element) {
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
if (element.style.position == 'absolute') {
|
||||
return;
|
||||
}
|
||||
MochiKit.Position.prepare();
|
||||
|
||||
var offsets = MochiKit.Position.positionedOffset(element);
|
||||
var width = element.clientWidth;
|
||||
var height = element.clientHeight;
|
||||
|
||||
var oldStyle = {
|
||||
'position': element.style.position,
|
||||
'left': offsets.x - parseFloat(element.style.left || 0),
|
||||
'top': offsets.y - parseFloat(element.style.top || 0),
|
||||
'width': element.style.width,
|
||||
'height': element.style.height
|
||||
};
|
||||
|
||||
element.style.position = 'absolute';
|
||||
element.style.top = offsets.y + 'px';
|
||||
element.style.left = offsets.x + 'px';
|
||||
element.style.width = width + 'px';
|
||||
element.style.height = height + 'px';
|
||||
|
||||
return oldStyle;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.positionedOffset */
|
||||
positionedOffset: function (element) {
|
||||
var valueT = 0, valueL = 0;
|
||||
do {
|
||||
valueT += element.offsetTop || 0;
|
||||
valueL += element.offsetLeft || 0;
|
||||
element = element.offsetParent;
|
||||
if (element) {
|
||||
p = MochiKit.Style.getStyle(element, 'position');
|
||||
if (p == 'relative' || p == 'absolute') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (element);
|
||||
return new MochiKit.Style.Coordinates(valueL, valueT);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.relativize */
|
||||
relativize: function (element, oldPos) {
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
if (element.style.position == 'relative') {
|
||||
return;
|
||||
}
|
||||
MochiKit.Position.prepare();
|
||||
|
||||
var top = parseFloat(element.style.top || 0) -
|
||||
(oldPos['top'] || 0);
|
||||
var left = parseFloat(element.style.left || 0) -
|
||||
(oldPos['left'] || 0);
|
||||
|
||||
element.style.position = oldPos['position'];
|
||||
element.style.top = top + 'px';
|
||||
element.style.left = left + 'px';
|
||||
element.style.width = oldPos['width'];
|
||||
element.style.height = oldPos['height'];
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.clone */
|
||||
clone: function (source, target) {
|
||||
source = MochiKit.DOM.getElement(source);
|
||||
target = MochiKit.DOM.getElement(target);
|
||||
target.style.position = 'absolute';
|
||||
var offsets = this.cumulativeOffset(source);
|
||||
target.style.top = offsets.y + 'px';
|
||||
target.style.left = offsets.x + 'px';
|
||||
target.style.width = source.offsetWidth + 'px';
|
||||
target.style.height = source.offsetHeight + 'px';
|
||||
},
|
||||
|
||||
/** @id MochiKit.Position.page */
|
||||
page: function (forElement) {
|
||||
var valueT = 0;
|
||||
var valueL = 0;
|
||||
|
||||
var element = forElement;
|
||||
do {
|
||||
valueT += element.offsetTop || 0;
|
||||
valueL += element.offsetLeft || 0;
|
||||
|
||||
// Safari fix
|
||||
if (element.offsetParent == document.body && MochiKit.Style.getStyle(element, 'position') == 'absolute') {
|
||||
break;
|
||||
}
|
||||
} while (element = element.offsetParent);
|
||||
|
||||
element = forElement;
|
||||
do {
|
||||
valueT -= element.scrollTop || 0;
|
||||
valueL -= element.scrollLeft || 0;
|
||||
} while (element = element.parentNode);
|
||||
|
||||
return new MochiKit.Style.Coordinates(valueL, valueT);
|
||||
}
|
||||
});
|
||||
|
||||
MochiKit.Position.__new__ = function (win) {
|
||||
var m = MochiKit.Base;
|
||||
this.EXPORT_TAGS = {
|
||||
':common': this.EXPORT,
|
||||
':all': m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
};
|
||||
|
||||
MochiKit.Position.__new__(this);
|
|
@ -0,0 +1,431 @@
|
|||
/***
|
||||
|
||||
MochiKit.Selector 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito and others. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Selector');
|
||||
dojo.require('MochiKit.Base');
|
||||
dojo.require('MochiKit.DOM');
|
||||
dojo.require('MochiKit.Iter');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
JSAN.use("MochiKit.DOM", []);
|
||||
JSAN.use("MochiKit.Iter", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) === 'undefined' ||
|
||||
typeof(MochiKit.DOM) === 'undefined' ||
|
||||
typeof(MochiKit.Iter) === 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Selector depends on MochiKit.Base, MochiKit.DOM and MochiKit.Iter!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Selector) == 'undefined') {
|
||||
MochiKit.Selector = {};
|
||||
}
|
||||
|
||||
MochiKit.Selector.NAME = "MochiKit.Selector";
|
||||
|
||||
MochiKit.Selector.VERSION = "1.4";
|
||||
|
||||
MochiKit.Selector.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
|
||||
MochiKit.Selector.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
MochiKit.Selector.EXPORT = [
|
||||
"Selector",
|
||||
"findChildElements",
|
||||
"findDocElements",
|
||||
"$$"
|
||||
];
|
||||
|
||||
MochiKit.Selector.EXPORT_OK = [
|
||||
];
|
||||
|
||||
MochiKit.Selector.Selector = function (expression) {
|
||||
this.params = {classNames: [], pseudoClassNames: []};
|
||||
this.expression = expression.toString().replace(/(^\s+|\s+$)/g, '');
|
||||
this.parseExpression();
|
||||
this.compileMatcher();
|
||||
};
|
||||
|
||||
MochiKit.Selector.Selector.prototype = {
|
||||
/***
|
||||
|
||||
Selector class: convenient object to make CSS selections.
|
||||
|
||||
***/
|
||||
__class__: MochiKit.Selector.Selector,
|
||||
|
||||
/** @id MochiKit.Selector.Selector.prototype.parseExpression */
|
||||
parseExpression: function () {
|
||||
function abort(message) {
|
||||
throw 'Parse error in selector: ' + message;
|
||||
}
|
||||
|
||||
if (this.expression == '') {
|
||||
abort('empty expression');
|
||||
}
|
||||
|
||||
var repr = MochiKit.Base.repr;
|
||||
var params = this.params;
|
||||
var expr = this.expression;
|
||||
var match, modifier, clause, rest;
|
||||
while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!^$*]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
|
||||
params.attributes = params.attributes || [];
|
||||
params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
|
||||
expr = match[1];
|
||||
}
|
||||
|
||||
if (expr == '*') {
|
||||
return this.params.wildcard = true;
|
||||
}
|
||||
|
||||
while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+(?:\([^)]*\))?)(.*)/i)) {
|
||||
modifier = match[1];
|
||||
clause = match[2];
|
||||
rest = match[3];
|
||||
switch (modifier) {
|
||||
case '#':
|
||||
params.id = clause;
|
||||
break;
|
||||
case '.':
|
||||
params.classNames.push(clause);
|
||||
break;
|
||||
case ':':
|
||||
params.pseudoClassNames.push(clause);
|
||||
break;
|
||||
case '':
|
||||
case undefined:
|
||||
params.tagName = clause.toUpperCase();
|
||||
break;
|
||||
default:
|
||||
abort(repr(expr));
|
||||
}
|
||||
expr = rest;
|
||||
}
|
||||
|
||||
if (expr.length > 0) {
|
||||
abort(repr(expr));
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Selector.Selector.prototype.buildMatchExpression */
|
||||
buildMatchExpression: function () {
|
||||
var repr = MochiKit.Base.repr;
|
||||
var params = this.params;
|
||||
var conditions = [];
|
||||
var clause, i;
|
||||
|
||||
function childElements(element) {
|
||||
return "MochiKit.Base.filter(function (node) { return node.nodeType == 1; }, " + element + ".childNodes)";
|
||||
}
|
||||
|
||||
if (params.wildcard) {
|
||||
conditions.push('true');
|
||||
}
|
||||
if (clause = params.id) {
|
||||
conditions.push('element.id == ' + repr(clause));
|
||||
}
|
||||
if (clause = params.tagName) {
|
||||
conditions.push('element.tagName.toUpperCase() == ' + repr(clause));
|
||||
}
|
||||
if ((clause = params.classNames).length > 0) {
|
||||
for (i = 0; i < clause.length; i++) {
|
||||
conditions.push('MochiKit.DOM.hasElementClass(element, ' + repr(clause[i]) + ')');
|
||||
}
|
||||
}
|
||||
if ((clause = params.pseudoClassNames).length > 0) {
|
||||
for (i = 0; i < clause.length; i++) {
|
||||
var match = clause[i].match(/^([^(]+)(?:\((.*)\))?$/);
|
||||
var pseudoClass = match[1];
|
||||
var pseudoClassArgument = match[2];
|
||||
switch (pseudoClass) {
|
||||
case 'root':
|
||||
conditions.push('element.nodeType == 9 || element === element.ownerDocument.documentElement'); break;
|
||||
case 'nth-child':
|
||||
case 'nth-last-child':
|
||||
case 'nth-of-type':
|
||||
case 'nth-last-of-type':
|
||||
match = pseudoClassArgument.match(/^((?:(\d+)n\+)?(\d+)|odd|even)$/);
|
||||
if (!match) {
|
||||
throw "Invalid argument to pseudo element nth-child: " + pseudoClassArgument;
|
||||
}
|
||||
var a, b;
|
||||
if (match[0] == 'odd') {
|
||||
a = 2;
|
||||
b = 1;
|
||||
} else if (match[0] == 'even') {
|
||||
a = 2;
|
||||
b = 0;
|
||||
} else {
|
||||
a = match[2] && parseInt(match) || null;
|
||||
b = parseInt(match[3]);
|
||||
}
|
||||
conditions.push('this.nthChild(element,' + a + ',' + b
|
||||
+ ',' + !!pseudoClass.match('^nth-last') // Reverse
|
||||
+ ',' + !!pseudoClass.match('of-type$') // Restrict to same tagName
|
||||
+ ')');
|
||||
break;
|
||||
case 'first-child':
|
||||
conditions.push('this.nthChild(element, null, 1)');
|
||||
break;
|
||||
case 'last-child':
|
||||
conditions.push('this.nthChild(element, null, 1, true)');
|
||||
break;
|
||||
case 'first-of-type':
|
||||
conditions.push('this.nthChild(element, null, 1, false, true)');
|
||||
break;
|
||||
case 'last-of-type':
|
||||
conditions.push('this.nthChild(element, null, 1, true, true)');
|
||||
break;
|
||||
case 'only-child':
|
||||
conditions.push(childElements('element.parentNode') + '.length == 1');
|
||||
break;
|
||||
case 'only-of-type':
|
||||
conditions.push('MochiKit.Base.filter(function (node) { return node.tagName == element.tagName; }, ' + childElements('element.parentNode') + ').length == 1');
|
||||
break;
|
||||
case 'empty':
|
||||
conditions.push('element.childNodes.length == 0');
|
||||
break;
|
||||
case 'enabled':
|
||||
conditions.push('(this.isUIElement(element) && element.disabled === false)');
|
||||
break;
|
||||
case 'disabled':
|
||||
conditions.push('(this.isUIElement(element) && element.disabled === true)');
|
||||
break;
|
||||
case 'checked':
|
||||
conditions.push('(this.isUIElement(element) && element.checked === true)');
|
||||
break;
|
||||
case 'not':
|
||||
var subselector = new MochiKit.Selector.Selector(pseudoClassArgument);
|
||||
conditions.push('!( ' + subselector.buildMatchExpression() + ')')
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clause = params.attributes) {
|
||||
MochiKit.Base.map(function (attribute) {
|
||||
var value = 'MochiKit.DOM.getNodeAttribute(element, ' + repr(attribute.name) + ')';
|
||||
var splitValueBy = function (delimiter) {
|
||||
return value + '.split(' + repr(delimiter) + ')';
|
||||
}
|
||||
|
||||
switch (attribute.operator) {
|
||||
case '=':
|
||||
conditions.push(value + ' == ' + repr(attribute.value));
|
||||
break;
|
||||
case '~=':
|
||||
conditions.push(value + ' && MochiKit.Base.findValue(' + splitValueBy(' ') + ', ' + repr(attribute.value) + ') > -1');
|
||||
break;
|
||||
case '^=':
|
||||
conditions.push(value + '.substring(0, ' + attribute.value.length + ') == ' + repr(attribute.value));
|
||||
break;
|
||||
case '$=':
|
||||
conditions.push(value + '.substring(' + value + '.length - ' + attribute.value.length + ') == ' + repr(attribute.value));
|
||||
break;
|
||||
case '*=':
|
||||
conditions.push(value + '.match(' + repr(attribute.value) + ')');
|
||||
break;
|
||||
case '|=':
|
||||
conditions.push(
|
||||
value + ' && ' + splitValueBy('-') + '[0].toUpperCase() == ' + repr(attribute.value.toUpperCase())
|
||||
);
|
||||
break;
|
||||
case '!=':
|
||||
conditions.push(value + ' != ' + repr(attribute.value));
|
||||
break;
|
||||
case '':
|
||||
case undefined:
|
||||
conditions.push(value + ' != null');
|
||||
break;
|
||||
default:
|
||||
throw 'Unknown operator ' + attribute.operator + ' in selector';
|
||||
}
|
||||
}, clause);
|
||||
}
|
||||
|
||||
return conditions.join(' && ');
|
||||
},
|
||||
|
||||
/** @id MochiKit.Selector.Selector.prototype.compileMatcher */
|
||||
compileMatcher: function () {
|
||||
this.match = new Function('element', 'if (!element.tagName) return false; \
|
||||
return ' + this.buildMatchExpression());
|
||||
},
|
||||
|
||||
/** @id MochiKit.Selector.Selector.prototype.nthChild */
|
||||
nthChild: function (element, a, b, reverse, sametag){
|
||||
var siblings = MochiKit.Base.filter(function (node) {
|
||||
return node.nodeType == 1;
|
||||
}, element.parentNode.childNodes);
|
||||
if (sametag) {
|
||||
siblings = MochiKit.Base.filter(function (node) {
|
||||
return node.tagName == element.tagName;
|
||||
}, siblings);
|
||||
}
|
||||
if (reverse) {
|
||||
siblings = MochiKit.Iter.reversed(siblings);
|
||||
}
|
||||
if (a) {
|
||||
var actualIndex = MochiKit.Base.findIdentical(siblings, element);
|
||||
return ((actualIndex + 1 - b) / a) % 1 == 0;
|
||||
} else {
|
||||
return b == MochiKit.Base.findIdentical(siblings, element) + 1;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Selector.Selector.prototype.isUIElement */
|
||||
isUIElement: function (element) {
|
||||
return MochiKit.Base.findValue(['input', 'button', 'select', 'option', 'textarea', 'object'],
|
||||
element.tagName.toLowerCase()) > -1;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Selector.Selector.prototype.findElements */
|
||||
findElements: function (scope, axis) {
|
||||
var element;
|
||||
|
||||
if (axis == undefined) {
|
||||
axis = "";
|
||||
}
|
||||
|
||||
function inScope(element, scope) {
|
||||
if (axis == "") {
|
||||
return MochiKit.DOM.isChildNode(element, scope);
|
||||
} else if (axis == ">") {
|
||||
return element.parentNode == scope;
|
||||
} else if (axis == "+") {
|
||||
return element == nextSiblingElement(scope);
|
||||
} else if (axis == "~") {
|
||||
var sibling = scope;
|
||||
while (sibling = nextSiblingElement(sibling)) {
|
||||
if (element == sibling) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
throw "Invalid axis: " + axis;
|
||||
}
|
||||
}
|
||||
|
||||
if (element = MochiKit.DOM.getElement(this.params.id)) {
|
||||
if (this.match(element)) {
|
||||
if (!scope || inScope(element, scope)) {
|
||||
return [element];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function nextSiblingElement(node) {
|
||||
node = node.nextSibling;
|
||||
while (node && node.nodeType != 1) {
|
||||
node = node.nextSibling;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
if (axis == "") {
|
||||
scope = (scope || MochiKit.DOM.currentDocument()).getElementsByTagName(this.params.tagName || '*');
|
||||
} else if (axis == ">") {
|
||||
if (!scope) {
|
||||
throw "> combinator not allowed without preceeding expression";
|
||||
}
|
||||
scope = MochiKit.Base.filter(function (node) {
|
||||
return node.nodeType == 1;
|
||||
}, scope.childNodes);
|
||||
} else if (axis == "+") {
|
||||
if (!scope) {
|
||||
throw "+ combinator not allowed without preceeding expression";
|
||||
}
|
||||
scope = nextSiblingElement(scope) && [nextSiblingElement(scope)];
|
||||
} else if (axis == "~") {
|
||||
if (!scope) {
|
||||
throw "~ combinator not allowed without preceeding expression";
|
||||
}
|
||||
var newscope = [];
|
||||
while (nextSiblingElement(scope)) {
|
||||
scope = nextSiblingElement(scope);
|
||||
newscope.push(scope);
|
||||
}
|
||||
scope = newscope;
|
||||
}
|
||||
|
||||
if (!scope) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var results = MochiKit.Base.filter(MochiKit.Base.bind(function (scopeElt) {
|
||||
return this.match(scopeElt);
|
||||
}, this), scope);
|
||||
|
||||
return results;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Selector.Selector.prototype.repr */
|
||||
repr: function () {
|
||||
return 'Selector(' + this.expression + ')';
|
||||
},
|
||||
|
||||
toString: MochiKit.Base.forwardCall("repr")
|
||||
};
|
||||
|
||||
MochiKit.Base.update(MochiKit.Selector, {
|
||||
|
||||
/** @id MochiKit.Selector.findChildElements */
|
||||
findChildElements: function (element, expressions) {
|
||||
return MochiKit.Base.flattenArray(MochiKit.Base.map(function (expression) {
|
||||
var nextScope = "";
|
||||
return MochiKit.Iter.reduce(function (results, expr) {
|
||||
if (match = expr.match(/^[>+~]$/)) {
|
||||
nextScope = match[0];
|
||||
return results;
|
||||
} else {
|
||||
var selector = new MochiKit.Selector.Selector(expr);
|
||||
var elements = MochiKit.Iter.reduce(function (elements, result) {
|
||||
return MochiKit.Base.extend(elements, selector.findElements(result || element, nextScope));
|
||||
}, results, []);
|
||||
nextScope = "";
|
||||
return elements;
|
||||
}
|
||||
}, expression.replace(/(^\s+|\s+$)/g, '').split(/\s+/), [null]);
|
||||
}, expressions));
|
||||
},
|
||||
|
||||
findDocElements: function () {
|
||||
return MochiKit.Selector.findChildElements(MochiKit.DOM.currentDocument(), arguments);
|
||||
},
|
||||
|
||||
__new__: function () {
|
||||
var m = MochiKit.Base;
|
||||
|
||||
this.$$ = this.findDocElements;
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
}
|
||||
});
|
||||
|
||||
MochiKit.Selector.__new__();
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Selector);
|
||||
|
|
@ -0,0 +1,899 @@
|
|||
/***
|
||||
|
||||
MochiKit.Signal 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2006 Jonathan Gardner, Beau Hartshorne, Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Signal');
|
||||
dojo.require('MochiKit.Base');
|
||||
dojo.require('MochiKit.DOM');
|
||||
dojo.require('MochiKit.Style');
|
||||
}
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use('MochiKit.Base', []);
|
||||
JSAN.use('MochiKit.DOM', []);
|
||||
JSAN.use('MochiKit.Style', []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined') {
|
||||
throw '';
|
||||
}
|
||||
} catch (e) {
|
||||
throw 'MochiKit.Signal depends on MochiKit.Base!';
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.DOM) == 'undefined') {
|
||||
throw '';
|
||||
}
|
||||
} catch (e) {
|
||||
throw 'MochiKit.Signal depends on MochiKit.DOM!';
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Style) == 'undefined') {
|
||||
throw '';
|
||||
}
|
||||
} catch (e) {
|
||||
throw 'MochiKit.Signal depends on MochiKit.Style!';
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Signal) == 'undefined') {
|
||||
MochiKit.Signal = {};
|
||||
}
|
||||
|
||||
MochiKit.Signal.NAME = 'MochiKit.Signal';
|
||||
MochiKit.Signal.VERSION = '1.4';
|
||||
|
||||
MochiKit.Signal._observers = [];
|
||||
|
||||
/** @id MochiKit.Signal.Event */
|
||||
MochiKit.Signal.Event = function (src, e) {
|
||||
this._event = e || window.event;
|
||||
this._src = src;
|
||||
};
|
||||
|
||||
MochiKit.Base.update(MochiKit.Signal.Event.prototype, {
|
||||
|
||||
__repr__: function () {
|
||||
var repr = MochiKit.Base.repr;
|
||||
var str = '{event(): ' + repr(this.event()) +
|
||||
', src(): ' + repr(this.src()) +
|
||||
', type(): ' + repr(this.type()) +
|
||||
', target(): ' + repr(this.target());
|
||||
|
||||
if (this.type() &&
|
||||
this.type().indexOf('key') === 0 ||
|
||||
this.type().indexOf('mouse') === 0 ||
|
||||
this.type().indexOf('click') != -1 ||
|
||||
this.type() == 'contextmenu') {
|
||||
str += ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) +
|
||||
', ctrl: ' + repr(this.modifier().ctrl) +
|
||||
', meta: ' + repr(this.modifier().meta) +
|
||||
', shift: ' + repr(this.modifier().shift) +
|
||||
', any: ' + repr(this.modifier().any) + '}';
|
||||
}
|
||||
|
||||
if (this.type() && this.type().indexOf('key') === 0) {
|
||||
str += ', key(): {code: ' + repr(this.key().code) +
|
||||
', string: ' + repr(this.key().string) + '}';
|
||||
}
|
||||
|
||||
if (this.type() && (
|
||||
this.type().indexOf('mouse') === 0 ||
|
||||
this.type().indexOf('click') != -1 ||
|
||||
this.type() == 'contextmenu')) {
|
||||
|
||||
str += ', mouse(): {page: ' + repr(this.mouse().page) +
|
||||
', client: ' + repr(this.mouse().client);
|
||||
|
||||
if (this.type() != 'mousemove') {
|
||||
str += ', button: {left: ' + repr(this.mouse().button.left) +
|
||||
', middle: ' + repr(this.mouse().button.middle) +
|
||||
', right: ' + repr(this.mouse().button.right) + '}}';
|
||||
} else {
|
||||
str += '}';
|
||||
}
|
||||
}
|
||||
if (this.type() == 'mouseover' || this.type() == 'mouseout') {
|
||||
str += ', relatedTarget(): ' + repr(this.relatedTarget());
|
||||
}
|
||||
str += '}';
|
||||
return str;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.toString */
|
||||
toString: function () {
|
||||
return this.__repr__();
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.src */
|
||||
src: function () {
|
||||
return this._src;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.event */
|
||||
event: function () {
|
||||
return this._event;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.type */
|
||||
type: function () {
|
||||
return this._event.type || undefined;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.target */
|
||||
target: function () {
|
||||
return this._event.target || this._event.srcElement;
|
||||
},
|
||||
|
||||
_relatedTarget: null,
|
||||
/** @id MochiKit.Signal.Event.prototype.relatedTarget */
|
||||
relatedTarget: function () {
|
||||
if (this._relatedTarget !== null) {
|
||||
return this._relatedTarget;
|
||||
}
|
||||
|
||||
var elem = null;
|
||||
if (this.type() == 'mouseover') {
|
||||
elem = (this._event.relatedTarget ||
|
||||
this._event.fromElement);
|
||||
} else if (this.type() == 'mouseout') {
|
||||
elem = (this._event.relatedTarget ||
|
||||
this._event.toElement);
|
||||
}
|
||||
if (elem !== null) {
|
||||
this._relatedTarget = elem;
|
||||
return elem;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
_modifier: null,
|
||||
/** @id MochiKit.Signal.Event.prototype.modifier */
|
||||
modifier: function () {
|
||||
if (this._modifier !== null) {
|
||||
return this._modifier;
|
||||
}
|
||||
var m = {};
|
||||
m.alt = this._event.altKey;
|
||||
m.ctrl = this._event.ctrlKey;
|
||||
m.meta = this._event.metaKey || false; // IE and Opera punt here
|
||||
m.shift = this._event.shiftKey;
|
||||
m.any = m.alt || m.ctrl || m.shift || m.meta;
|
||||
this._modifier = m;
|
||||
return m;
|
||||
},
|
||||
|
||||
_key: null,
|
||||
/** @id MochiKit.Signal.Event.prototype.key */
|
||||
key: function () {
|
||||
if (this._key !== null) {
|
||||
return this._key;
|
||||
}
|
||||
var k = {};
|
||||
if (this.type() && this.type().indexOf('key') === 0) {
|
||||
|
||||
/*
|
||||
|
||||
If you're looking for a special key, look for it in keydown or
|
||||
keyup, but never keypress. If you're looking for a Unicode
|
||||
chracter, look for it with keypress, but never keyup or
|
||||
keydown.
|
||||
|
||||
Notes:
|
||||
|
||||
FF key event behavior:
|
||||
key event charCode keyCode
|
||||
DOWN ku,kd 0 40
|
||||
DOWN kp 0 40
|
||||
ESC ku,kd 0 27
|
||||
ESC kp 0 27
|
||||
a ku,kd 0 65
|
||||
a kp 97 0
|
||||
shift+a ku,kd 0 65
|
||||
shift+a kp 65 0
|
||||
1 ku,kd 0 49
|
||||
1 kp 49 0
|
||||
shift+1 ku,kd 0 0
|
||||
shift+1 kp 33 0
|
||||
|
||||
IE key event behavior:
|
||||
(IE doesn't fire keypress events for special keys.)
|
||||
key event keyCode
|
||||
DOWN ku,kd 40
|
||||
DOWN kp undefined
|
||||
ESC ku,kd 27
|
||||
ESC kp 27
|
||||
a ku,kd 65
|
||||
a kp 97
|
||||
shift+a ku,kd 65
|
||||
shift+a kp 65
|
||||
1 ku,kd 49
|
||||
1 kp 49
|
||||
shift+1 ku,kd 49
|
||||
shift+1 kp 33
|
||||
|
||||
Safari key event behavior:
|
||||
(Safari sets charCode and keyCode to something crazy for
|
||||
special keys.)
|
||||
key event charCode keyCode
|
||||
DOWN ku,kd 63233 40
|
||||
DOWN kp 63233 63233
|
||||
ESC ku,kd 27 27
|
||||
ESC kp 27 27
|
||||
a ku,kd 97 65
|
||||
a kp 97 97
|
||||
shift+a ku,kd 65 65
|
||||
shift+a kp 65 65
|
||||
1 ku,kd 49 49
|
||||
1 kp 49 49
|
||||
shift+1 ku,kd 33 49
|
||||
shift+1 kp 33 33
|
||||
|
||||
*/
|
||||
|
||||
/* look for special keys here */
|
||||
if (this.type() == 'keydown' || this.type() == 'keyup') {
|
||||
k.code = this._event.keyCode;
|
||||
k.string = (MochiKit.Signal._specialKeys[k.code] ||
|
||||
'KEY_UNKNOWN');
|
||||
this._key = k;
|
||||
return k;
|
||||
|
||||
/* look for characters here */
|
||||
} else if (this.type() == 'keypress') {
|
||||
|
||||
/*
|
||||
|
||||
Special key behavior:
|
||||
|
||||
IE: does not fire keypress events for special keys
|
||||
FF: sets charCode to 0, and sets the correct keyCode
|
||||
Safari: sets keyCode and charCode to something stupid
|
||||
|
||||
*/
|
||||
|
||||
k.code = 0;
|
||||
k.string = '';
|
||||
|
||||
if (typeof(this._event.charCode) != 'undefined' &&
|
||||
this._event.charCode !== 0 &&
|
||||
!MochiKit.Signal._specialMacKeys[this._event.charCode]) {
|
||||
k.code = this._event.charCode;
|
||||
k.string = String.fromCharCode(k.code);
|
||||
} else if (this._event.keyCode &&
|
||||
typeof(this._event.charCode) == 'undefined') { // IE
|
||||
k.code = this._event.keyCode;
|
||||
k.string = String.fromCharCode(k.code);
|
||||
}
|
||||
|
||||
this._key = k;
|
||||
return k;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
_mouse: null,
|
||||
/** @id MochiKit.Signal.Event.prototype.mouse */
|
||||
mouse: function () {
|
||||
if (this._mouse !== null) {
|
||||
return this._mouse;
|
||||
}
|
||||
|
||||
var m = {};
|
||||
var e = this._event;
|
||||
|
||||
if (this.type() && (
|
||||
this.type().indexOf('mouse') === 0 ||
|
||||
this.type().indexOf('click') != -1 ||
|
||||
this.type() == 'contextmenu')) {
|
||||
|
||||
m.client = new MochiKit.Style.Coordinates(0, 0);
|
||||
if (e.clientX || e.clientY) {
|
||||
m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX;
|
||||
m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY;
|
||||
}
|
||||
|
||||
m.page = new MochiKit.Style.Coordinates(0, 0);
|
||||
if (e.pageX || e.pageY) {
|
||||
m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX;
|
||||
m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY;
|
||||
} else {
|
||||
/*
|
||||
|
||||
The IE shortcut can be off by two. We fix it. See:
|
||||
http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
|
||||
|
||||
This is similar to the method used in
|
||||
MochiKit.Style.getElementPosition().
|
||||
|
||||
*/
|
||||
var de = MochiKit.DOM._document.documentElement;
|
||||
var b = MochiKit.DOM._document.body;
|
||||
|
||||
m.page.x = e.clientX +
|
||||
(de.scrollLeft || b.scrollLeft) -
|
||||
(de.clientLeft || 0);
|
||||
|
||||
m.page.y = e.clientY +
|
||||
(de.scrollTop || b.scrollTop) -
|
||||
(de.clientTop || 0);
|
||||
|
||||
}
|
||||
if (this.type() != 'mousemove') {
|
||||
m.button = {};
|
||||
m.button.left = false;
|
||||
m.button.right = false;
|
||||
m.button.middle = false;
|
||||
|
||||
/* we could check e.button, but which is more consistent */
|
||||
if (e.which) {
|
||||
m.button.left = (e.which == 1);
|
||||
m.button.middle = (e.which == 2);
|
||||
m.button.right = (e.which == 3);
|
||||
|
||||
/*
|
||||
|
||||
Mac browsers and right click:
|
||||
|
||||
- Safari doesn't fire any click events on a right
|
||||
click:
|
||||
http://bugs.webkit.org/show_bug.cgi?id=6595
|
||||
|
||||
- Firefox fires the event, and sets ctrlKey = true
|
||||
|
||||
- Opera fires the event, and sets metaKey = true
|
||||
|
||||
oncontextmenu is fired on right clicks between
|
||||
browsers and across platforms.
|
||||
|
||||
*/
|
||||
|
||||
} else {
|
||||
m.button.left = !!(e.button & 1);
|
||||
m.button.right = !!(e.button & 2);
|
||||
m.button.middle = !!(e.button & 4);
|
||||
}
|
||||
}
|
||||
this._mouse = m;
|
||||
return m;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.stop */
|
||||
stop: function () {
|
||||
this.stopPropagation();
|
||||
this.preventDefault();
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.stopPropagation */
|
||||
stopPropagation: function () {
|
||||
if (this._event.stopPropagation) {
|
||||
this._event.stopPropagation();
|
||||
} else {
|
||||
this._event.cancelBubble = true;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.preventDefault */
|
||||
preventDefault: function () {
|
||||
if (this._event.preventDefault) {
|
||||
this._event.preventDefault();
|
||||
} else if (this._confirmUnload === null) {
|
||||
this._event.returnValue = false;
|
||||
}
|
||||
},
|
||||
|
||||
_confirmUnload: null,
|
||||
|
||||
/** @id MochiKit.Signal.Event.prototype.confirmUnload */
|
||||
confirmUnload: function (msg) {
|
||||
if (this.type() == 'beforeunload') {
|
||||
this._confirmUnload = msg;
|
||||
this._event.returnValue = msg;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Safari sets keyCode to these special values onkeypress. */
|
||||
MochiKit.Signal._specialMacKeys = {
|
||||
3: 'KEY_ENTER',
|
||||
63289: 'KEY_NUM_PAD_CLEAR',
|
||||
63276: 'KEY_PAGE_UP',
|
||||
63277: 'KEY_PAGE_DOWN',
|
||||
63275: 'KEY_END',
|
||||
63273: 'KEY_HOME',
|
||||
63234: 'KEY_ARROW_LEFT',
|
||||
63232: 'KEY_ARROW_UP',
|
||||
63235: 'KEY_ARROW_RIGHT',
|
||||
63233: 'KEY_ARROW_DOWN',
|
||||
63302: 'KEY_INSERT',
|
||||
63272: 'KEY_DELETE'
|
||||
};
|
||||
|
||||
/* for KEY_F1 - KEY_F12 */
|
||||
(function () {
|
||||
var _specialMacKeys = MochiKit.Signal._specialMacKeys;
|
||||
for (i = 63236; i <= 63242; i++) {
|
||||
// no F0
|
||||
_specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1);
|
||||
}
|
||||
})();
|
||||
|
||||
/* Standard keyboard key codes. */
|
||||
MochiKit.Signal._specialKeys = {
|
||||
8: 'KEY_BACKSPACE',
|
||||
9: 'KEY_TAB',
|
||||
12: 'KEY_NUM_PAD_CLEAR', // weird, for Safari and Mac FF only
|
||||
13: 'KEY_ENTER',
|
||||
16: 'KEY_SHIFT',
|
||||
17: 'KEY_CTRL',
|
||||
18: 'KEY_ALT',
|
||||
19: 'KEY_PAUSE',
|
||||
20: 'KEY_CAPS_LOCK',
|
||||
27: 'KEY_ESCAPE',
|
||||
32: 'KEY_SPACEBAR',
|
||||
33: 'KEY_PAGE_UP',
|
||||
34: 'KEY_PAGE_DOWN',
|
||||
35: 'KEY_END',
|
||||
36: 'KEY_HOME',
|
||||
37: 'KEY_ARROW_LEFT',
|
||||
38: 'KEY_ARROW_UP',
|
||||
39: 'KEY_ARROW_RIGHT',
|
||||
40: 'KEY_ARROW_DOWN',
|
||||
44: 'KEY_PRINT_SCREEN',
|
||||
45: 'KEY_INSERT',
|
||||
46: 'KEY_DELETE',
|
||||
59: 'KEY_SEMICOLON', // weird, for Safari and IE only
|
||||
91: 'KEY_WINDOWS_LEFT',
|
||||
92: 'KEY_WINDOWS_RIGHT',
|
||||
93: 'KEY_SELECT',
|
||||
106: 'KEY_NUM_PAD_ASTERISK',
|
||||
107: 'KEY_NUM_PAD_PLUS_SIGN',
|
||||
109: 'KEY_NUM_PAD_HYPHEN-MINUS',
|
||||
110: 'KEY_NUM_PAD_FULL_STOP',
|
||||
111: 'KEY_NUM_PAD_SOLIDUS',
|
||||
144: 'KEY_NUM_LOCK',
|
||||
145: 'KEY_SCROLL_LOCK',
|
||||
186: 'KEY_SEMICOLON',
|
||||
187: 'KEY_EQUALS_SIGN',
|
||||
188: 'KEY_COMMA',
|
||||
189: 'KEY_HYPHEN-MINUS',
|
||||
190: 'KEY_FULL_STOP',
|
||||
191: 'KEY_SOLIDUS',
|
||||
192: 'KEY_GRAVE_ACCENT',
|
||||
219: 'KEY_LEFT_SQUARE_BRACKET',
|
||||
220: 'KEY_REVERSE_SOLIDUS',
|
||||
221: 'KEY_RIGHT_SQUARE_BRACKET',
|
||||
222: 'KEY_APOSTROPHE'
|
||||
// undefined: 'KEY_UNKNOWN'
|
||||
};
|
||||
|
||||
(function () {
|
||||
/* for KEY_0 - KEY_9 */
|
||||
var _specialKeys = MochiKit.Signal._specialKeys;
|
||||
for (var i = 48; i <= 57; i++) {
|
||||
_specialKeys[i] = 'KEY_' + (i - 48);
|
||||
}
|
||||
|
||||
/* for KEY_A - KEY_Z */
|
||||
for (i = 65; i <= 90; i++) {
|
||||
_specialKeys[i] = 'KEY_' + String.fromCharCode(i);
|
||||
}
|
||||
|
||||
/* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */
|
||||
for (i = 96; i <= 105; i++) {
|
||||
_specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96);
|
||||
}
|
||||
|
||||
/* for KEY_F1 - KEY_F12 */
|
||||
for (i = 112; i <= 123; i++) {
|
||||
// no F0
|
||||
_specialKeys[i] = 'KEY_F' + (i - 112 + 1);
|
||||
}
|
||||
})();
|
||||
|
||||
/* Internal object to keep track of created signals. */
|
||||
MochiKit.Signal.Ident = function (ident) {
|
||||
this.source = ident.source;
|
||||
this.signal = ident.signal;
|
||||
this.listener = ident.listener;
|
||||
this.isDOM = ident.isDOM;
|
||||
this.objOrFunc = ident.objOrFunc;
|
||||
this.funcOrStr = ident.funcOrStr;
|
||||
this.connected = ident.connected;
|
||||
};
|
||||
|
||||
MochiKit.Signal.Ident.prototype = {};
|
||||
|
||||
MochiKit.Base.update(MochiKit.Signal, {
|
||||
|
||||
__repr__: function () {
|
||||
return '[' + this.NAME + ' ' + this.VERSION + ']';
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return this.__repr__();
|
||||
},
|
||||
|
||||
_unloadCache: function () {
|
||||
var self = MochiKit.Signal;
|
||||
var observers = self._observers;
|
||||
|
||||
for (var i = 0; i < observers.length; i++) {
|
||||
if (observers[i].signal !== 'onload' && observers[i].signal !== 'onunload') {
|
||||
self._disconnect(observers[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_listener: function (src, sig, func, obj, isDOM) {
|
||||
var self = MochiKit.Signal;
|
||||
var E = self.Event;
|
||||
if (!isDOM) {
|
||||
return MochiKit.Base.bind(func, obj);
|
||||
}
|
||||
obj = obj || src;
|
||||
if (typeof(func) == "string") {
|
||||
if (sig === 'onload' || sig === 'onunload') {
|
||||
return function (nativeEvent) {
|
||||
obj[func].apply(obj, [new E(src, nativeEvent)]);
|
||||
|
||||
var ident = new MochiKit.Signal.Ident({
|
||||
source: src, signal: sig, objOrFunc: obj, funcOrStr: func});
|
||||
|
||||
MochiKit.Signal._disconnect(ident);
|
||||
};
|
||||
} else {
|
||||
return function (nativeEvent) {
|
||||
obj[func].apply(obj, [new E(src, nativeEvent)]);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (sig === 'onload' || sig === 'onunload') {
|
||||
return function (nativeEvent) {
|
||||
func.apply(obj, [new E(src, nativeEvent)]);
|
||||
MochiKit.Signal.disconnect(src, sig, func);
|
||||
|
||||
var ident = new MochiKit.Signal.Ident({
|
||||
source: src, signal: sig, objOrFunc: func});
|
||||
|
||||
MochiKit.Signal._disconnect(ident);
|
||||
};
|
||||
} else {
|
||||
return function (nativeEvent) {
|
||||
func.apply(obj, [new E(src, nativeEvent)]);
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_browserAlreadyHasMouseEnterAndLeave: function () {
|
||||
return /MSIE/.test(navigator.userAgent);
|
||||
},
|
||||
|
||||
_mouseEnterListener: function (src, sig, func, obj) {
|
||||
var E = MochiKit.Signal.Event;
|
||||
return function (nativeEvent) {
|
||||
var e = new E(src, nativeEvent);
|
||||
try {
|
||||
e.relatedTarget().nodeName;
|
||||
} catch (err) {
|
||||
/* probably hit a permission denied error; possibly one of
|
||||
* firefox's screwy anonymous DIVs inside an input element.
|
||||
* Allow this event to propogate up.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
e.stop();
|
||||
if (MochiKit.DOM.isChildNode(e.relatedTarget(), src)) {
|
||||
/* We've moved between our node and a child. Ignore. */
|
||||
return;
|
||||
}
|
||||
e.type = function () { return sig; };
|
||||
if (typeof(func) == "string") {
|
||||
return obj[func].apply(obj, [e]);
|
||||
} else {
|
||||
return func.apply(obj, [e]);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
_getDestPair: function (objOrFunc, funcOrStr) {
|
||||
var obj = null;
|
||||
var func = null;
|
||||
if (typeof(funcOrStr) != 'undefined') {
|
||||
obj = objOrFunc;
|
||||
func = funcOrStr;
|
||||
if (typeof(funcOrStr) == 'string') {
|
||||
if (typeof(objOrFunc[funcOrStr]) != "function") {
|
||||
throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
|
||||
}
|
||||
} else if (typeof(funcOrStr) != 'function') {
|
||||
throw new Error("'funcOrStr' must be a function or string");
|
||||
}
|
||||
} else if (typeof(objOrFunc) != "function") {
|
||||
throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
|
||||
} else {
|
||||
func = objOrFunc;
|
||||
}
|
||||
return [obj, func];
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.connect */
|
||||
connect: function (src, sig, objOrFunc/* optional */, funcOrStr) {
|
||||
src = MochiKit.DOM.getElement(src);
|
||||
var self = MochiKit.Signal;
|
||||
|
||||
if (typeof(sig) != 'string') {
|
||||
throw new Error("'sig' must be a string");
|
||||
}
|
||||
|
||||
var destPair = self._getDestPair(objOrFunc, funcOrStr);
|
||||
var obj = destPair[0];
|
||||
var func = destPair[1];
|
||||
if (typeof(obj) == 'undefined' || obj === null) {
|
||||
obj = src;
|
||||
}
|
||||
|
||||
var isDOM = !!(src.addEventListener || src.attachEvent);
|
||||
if (isDOM && (sig === "onmouseenter" || sig === "onmouseleave")
|
||||
&& !self._browserAlreadyHasMouseEnterAndLeave()) {
|
||||
var listener = self._mouseEnterListener(src, sig.substr(2), func, obj);
|
||||
if (sig === "onmouseenter") {
|
||||
sig = "onmouseover";
|
||||
} else {
|
||||
sig = "onmouseout";
|
||||
}
|
||||
} else {
|
||||
var listener = self._listener(src, sig, func, obj, isDOM);
|
||||
}
|
||||
|
||||
if (src.addEventListener) {
|
||||
src.addEventListener(sig.substr(2), listener, false);
|
||||
} else if (src.attachEvent) {
|
||||
src.attachEvent(sig, listener); // useCapture unsupported
|
||||
}
|
||||
|
||||
var ident = new MochiKit.Signal.Ident({
|
||||
source: src,
|
||||
signal: sig,
|
||||
listener: listener,
|
||||
isDOM: isDOM,
|
||||
objOrFunc: objOrFunc,
|
||||
funcOrStr: funcOrStr,
|
||||
connected: true
|
||||
});
|
||||
self._observers.push(ident);
|
||||
|
||||
if (!isDOM && typeof(src.__connect__) == 'function') {
|
||||
var args = MochiKit.Base.extend([ident], arguments, 1);
|
||||
src.__connect__.apply(src, args);
|
||||
}
|
||||
|
||||
return ident;
|
||||
},
|
||||
|
||||
_disconnect: function (ident) {
|
||||
// already disconnected
|
||||
if (!ident.connected) {
|
||||
return;
|
||||
}
|
||||
ident.connected = false;
|
||||
// check isDOM
|
||||
if (!ident.isDOM) {
|
||||
return;
|
||||
}
|
||||
var src = ident.source;
|
||||
var sig = ident.signal;
|
||||
var listener = ident.listener;
|
||||
|
||||
if (src.removeEventListener) {
|
||||
src.removeEventListener(sig.substr(2), listener, false);
|
||||
} else if (src.detachEvent) {
|
||||
src.detachEvent(sig, listener); // useCapture unsupported
|
||||
} else {
|
||||
throw new Error("'src' must be a DOM element");
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.disconnect */
|
||||
disconnect: function (ident) {
|
||||
var self = MochiKit.Signal;
|
||||
var observers = self._observers;
|
||||
var m = MochiKit.Base;
|
||||
if (arguments.length > 1) {
|
||||
// compatibility API
|
||||
var src = MochiKit.DOM.getElement(arguments[0]);
|
||||
var sig = arguments[1];
|
||||
var obj = arguments[2];
|
||||
var func = arguments[3];
|
||||
for (var i = observers.length - 1; i >= 0; i--) {
|
||||
var o = observers[i];
|
||||
if (o.source === src && o.signal === sig && o.objOrFunc === obj && o.funcOrStr === func) {
|
||||
self._disconnect(o);
|
||||
if (!self._lock) {
|
||||
observers.splice(i, 1);
|
||||
} else {
|
||||
self._dirty = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var idx = m.findIdentical(observers, ident);
|
||||
if (idx >= 0) {
|
||||
self._disconnect(ident);
|
||||
if (!self._lock) {
|
||||
observers.splice(idx, 1);
|
||||
} else {
|
||||
self._dirty = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.disconnectAllTo */
|
||||
disconnectAllTo: function (objOrFunc, /* optional */funcOrStr) {
|
||||
var self = MochiKit.Signal;
|
||||
var observers = self._observers;
|
||||
var disconnect = self._disconnect;
|
||||
var locked = self._lock;
|
||||
var dirty = self._dirty;
|
||||
if (typeof(funcOrStr) === 'undefined') {
|
||||
funcOrStr = null;
|
||||
}
|
||||
for (var i = observers.length - 1; i >= 0; i--) {
|
||||
var ident = observers[i];
|
||||
if (ident.objOrFunc === objOrFunc &&
|
||||
(funcOrStr === null || ident.funcOrStr === funcOrStr)) {
|
||||
disconnect(ident);
|
||||
if (locked) {
|
||||
dirty = true;
|
||||
} else {
|
||||
observers.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
self._dirty = dirty;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.disconnectAll */
|
||||
disconnectAll: function (src/* optional */, sig) {
|
||||
src = MochiKit.DOM.getElement(src);
|
||||
var m = MochiKit.Base;
|
||||
var signals = m.flattenArguments(m.extend(null, arguments, 1));
|
||||
var self = MochiKit.Signal;
|
||||
var disconnect = self._disconnect;
|
||||
var observers = self._observers;
|
||||
var i, ident;
|
||||
var locked = self._lock;
|
||||
var dirty = self._dirty;
|
||||
if (signals.length === 0) {
|
||||
// disconnect all
|
||||
for (i = observers.length - 1; i >= 0; i--) {
|
||||
ident = observers[i];
|
||||
if (ident.source === src) {
|
||||
disconnect(ident);
|
||||
if (!locked) {
|
||||
observers.splice(i, 1);
|
||||
} else {
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var sigs = {};
|
||||
for (i = 0; i < signals.length; i++) {
|
||||
sigs[signals[i]] = true;
|
||||
}
|
||||
for (i = observers.length - 1; i >= 0; i--) {
|
||||
ident = observers[i];
|
||||
if (ident.source === src && ident.signal in sigs) {
|
||||
disconnect(ident);
|
||||
if (!locked) {
|
||||
observers.splice(i, 1);
|
||||
} else {
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self._dirty = dirty;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Signal.signal */
|
||||
signal: function (src, sig) {
|
||||
var self = MochiKit.Signal;
|
||||
var observers = self._observers;
|
||||
src = MochiKit.DOM.getElement(src);
|
||||
var args = MochiKit.Base.extend(null, arguments, 2);
|
||||
var errors = [];
|
||||
self._lock = true;
|
||||
for (var i = 0; i < observers.length; i++) {
|
||||
var ident = observers[i];
|
||||
if (ident.source === src && ident.signal === sig &&
|
||||
ident.connected) {
|
||||
try {
|
||||
ident.listener.apply(src, args);
|
||||
} catch (e) {
|
||||
errors.push(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
self._lock = false;
|
||||
if (self._dirty) {
|
||||
self._dirty = false;
|
||||
for (var i = observers.length - 1; i >= 0; i--) {
|
||||
if (!observers[i].connected) {
|
||||
observers.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errors.length == 1) {
|
||||
throw errors[0];
|
||||
} else if (errors.length > 1) {
|
||||
var e = new Error("Multiple errors thrown in handling 'sig', see errors property");
|
||||
e.errors = errors;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
MochiKit.Signal.EXPORT_OK = [];
|
||||
|
||||
MochiKit.Signal.EXPORT = [
|
||||
'connect',
|
||||
'disconnect',
|
||||
'signal',
|
||||
'disconnectAll',
|
||||
'disconnectAllTo'
|
||||
];
|
||||
|
||||
MochiKit.Signal.__new__ = function (win) {
|
||||
var m = MochiKit.Base;
|
||||
this._document = document;
|
||||
this._window = win;
|
||||
this._lock = false;
|
||||
this._dirty = false;
|
||||
|
||||
try {
|
||||
this.connect(window, 'onunload', this._unloadCache);
|
||||
} catch (e) {
|
||||
// pass: might not be a browser
|
||||
}
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
':common': this.EXPORT,
|
||||
':all': m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
};
|
||||
|
||||
MochiKit.Signal.__new__(this);
|
||||
|
||||
//
|
||||
// XXX: Internet Explorer blows
|
||||
//
|
||||
if (MochiKit.__export__) {
|
||||
connect = MochiKit.Signal.connect;
|
||||
disconnect = MochiKit.Signal.disconnect;
|
||||
disconnectAll = MochiKit.Signal.disconnectAll;
|
||||
signal = MochiKit.Signal.signal;
|
||||
}
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Signal);
|
|
@ -0,0 +1,589 @@
|
|||
/***
|
||||
Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
Mochi-ized By Thomas Herve (_firstname_@nimail.org)
|
||||
|
||||
See scriptaculous.js for full license.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Sortable');
|
||||
dojo.require('MochiKit.Base');
|
||||
dojo.require('MochiKit.DOM');
|
||||
dojo.require('MochiKit.Iter');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
JSAN.use("MochiKit.DOM", []);
|
||||
JSAN.use("MochiKit.Iter", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined' ||
|
||||
typeof(MochiKit.DOM) == 'undefined' ||
|
||||
typeof(MochiKit.Iter) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.DragAndDrop depends on MochiKit.Base, MochiKit.DOM and MochiKit.Iter!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Sortable) == 'undefined') {
|
||||
MochiKit.Sortable = {};
|
||||
}
|
||||
|
||||
MochiKit.Sortable.NAME = 'MochiKit.Sortable';
|
||||
MochiKit.Sortable.VERSION = '1.4';
|
||||
|
||||
MochiKit.Sortable.__repr__ = function () {
|
||||
return '[' + this.NAME + ' ' + this.VERSION + ']';
|
||||
};
|
||||
|
||||
MochiKit.Sortable.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
MochiKit.Sortable.EXPORT = [
|
||||
];
|
||||
|
||||
MochiKit.Sortable.EXPORT_OK = [
|
||||
];
|
||||
|
||||
MochiKit.Base.update(MochiKit.Sortable, {
|
||||
/***
|
||||
|
||||
Manage sortables. Mainly use the create function to add a sortable.
|
||||
|
||||
***/
|
||||
sortables: {},
|
||||
|
||||
_findRootElement: function (element) {
|
||||
while (element.tagName.toUpperCase() != "BODY") {
|
||||
if (element.id && MochiKit.Sortable.sortables[element.id]) {
|
||||
return element;
|
||||
}
|
||||
element = element.parentNode;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.options */
|
||||
options: function (element) {
|
||||
element = MochiKit.Sortable._findRootElement(MochiKit.DOM.getElement(element));
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
return MochiKit.Sortable.sortables[element.id];
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.destroy */
|
||||
destroy: function (element){
|
||||
var s = MochiKit.Sortable.options(element);
|
||||
var b = MochiKit.Base;
|
||||
var d = MochiKit.DragAndDrop;
|
||||
|
||||
if (s) {
|
||||
MochiKit.Signal.disconnect(s.startHandle);
|
||||
MochiKit.Signal.disconnect(s.endHandle);
|
||||
b.map(function (dr) {
|
||||
d.Droppables.remove(dr);
|
||||
}, s.droppables);
|
||||
b.map(function (dr) {
|
||||
dr.destroy();
|
||||
}, s.draggables);
|
||||
|
||||
delete MochiKit.Sortable.sortables[s.element.id];
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.create */
|
||||
create: function (element, options) {
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
var self = MochiKit.Sortable;
|
||||
|
||||
/** @id MochiKit.Sortable.options */
|
||||
options = MochiKit.Base.update({
|
||||
|
||||
/** @id MochiKit.Sortable.element */
|
||||
element: element,
|
||||
|
||||
/** @id MochiKit.Sortable.tag */
|
||||
tag: 'li', // assumes li children, override with tag: 'tagname'
|
||||
|
||||
/** @id MochiKit.Sortable.dropOnEmpty */
|
||||
dropOnEmpty: false,
|
||||
|
||||
/** @id MochiKit.Sortable.tree */
|
||||
tree: false,
|
||||
|
||||
/** @id MochiKit.Sortable.treeTag */
|
||||
treeTag: 'ul',
|
||||
|
||||
/** @id MochiKit.Sortable.overlap */
|
||||
overlap: 'vertical', // one of 'vertical', 'horizontal'
|
||||
|
||||
/** @id MochiKit.Sortable.constraint */
|
||||
constraint: 'vertical', // one of 'vertical', 'horizontal', false
|
||||
// also takes array of elements (or ids); or false
|
||||
|
||||
/** @id MochiKit.Sortable.containment */
|
||||
containment: [element],
|
||||
|
||||
/** @id MochiKit.Sortable.handle */
|
||||
handle: false, // or a CSS class
|
||||
|
||||
/** @id MochiKit.Sortable.only */
|
||||
only: false,
|
||||
|
||||
/** @id MochiKit.Sortable.hoverclass */
|
||||
hoverclass: null,
|
||||
|
||||
/** @id MochiKit.Sortable.ghosting */
|
||||
ghosting: false,
|
||||
|
||||
/** @id MochiKit.Sortable.scroll */
|
||||
scroll: false,
|
||||
|
||||
/** @id MochiKit.Sortable.scrollSensitivity */
|
||||
scrollSensitivity: 20,
|
||||
|
||||
/** @id MochiKit.Sortable.scrollSpeed */
|
||||
scrollSpeed: 15,
|
||||
|
||||
/** @id MochiKit.Sortable.format */
|
||||
format: /^[^_]*_(.*)$/,
|
||||
|
||||
/** @id MochiKit.Sortable.onChange */
|
||||
onChange: MochiKit.Base.noop,
|
||||
|
||||
/** @id MochiKit.Sortable.onUpdate */
|
||||
onUpdate: MochiKit.Base.noop,
|
||||
|
||||
/** @id MochiKit.Sortable.accept */
|
||||
accept: null
|
||||
}, options);
|
||||
|
||||
// clear any old sortable with same element
|
||||
self.destroy(element);
|
||||
|
||||
// build options for the draggables
|
||||
var options_for_draggable = {
|
||||
revert: true,
|
||||
ghosting: options.ghosting,
|
||||
scroll: options.scroll,
|
||||
scrollSensitivity: options.scrollSensitivity,
|
||||
scrollSpeed: options.scrollSpeed,
|
||||
constraint: options.constraint,
|
||||
handle: options.handle
|
||||
};
|
||||
|
||||
if (options.starteffect) {
|
||||
options_for_draggable.starteffect = options.starteffect;
|
||||
}
|
||||
|
||||
if (options.reverteffect) {
|
||||
options_for_draggable.reverteffect = options.reverteffect;
|
||||
} else if (options.ghosting) {
|
||||
options_for_draggable.reverteffect = function (innerelement) {
|
||||
innerelement.style.top = 0;
|
||||
innerelement.style.left = 0;
|
||||
};
|
||||
}
|
||||
|
||||
if (options.endeffect) {
|
||||
options_for_draggable.endeffect = options.endeffect;
|
||||
}
|
||||
|
||||
if (options.zindex) {
|
||||
options_for_draggable.zindex = options.zindex;
|
||||
}
|
||||
|
||||
// build options for the droppables
|
||||
var options_for_droppable = {
|
||||
overlap: options.overlap,
|
||||
containment: options.containment,
|
||||
hoverclass: options.hoverclass,
|
||||
onhover: self.onHover,
|
||||
tree: options.tree,
|
||||
accept: options.accept
|
||||
}
|
||||
|
||||
var options_for_tree = {
|
||||
onhover: self.onEmptyHover,
|
||||
overlap: options.overlap,
|
||||
containment: options.containment,
|
||||
hoverclass: options.hoverclass,
|
||||
accept: options.accept
|
||||
}
|
||||
|
||||
// fix for gecko engine
|
||||
MochiKit.DOM.removeEmptyTextNodes(element);
|
||||
|
||||
options.draggables = [];
|
||||
options.droppables = [];
|
||||
|
||||
// drop on empty handling
|
||||
if (options.dropOnEmpty || options.tree) {
|
||||
new MochiKit.DragAndDrop.Droppable(element, options_for_tree);
|
||||
options.droppables.push(element);
|
||||
}
|
||||
MochiKit.Base.map(function (e) {
|
||||
// handles are per-draggable
|
||||
var handle = options.handle ?
|
||||
MochiKit.DOM.getFirstElementByTagAndClassName(null,
|
||||
options.handle, e) : e;
|
||||
options.draggables.push(
|
||||
new MochiKit.DragAndDrop.Draggable(e,
|
||||
MochiKit.Base.update(options_for_draggable,
|
||||
{handle: handle})));
|
||||
new MochiKit.DragAndDrop.Droppable(e, options_for_droppable);
|
||||
if (options.tree) {
|
||||
e.treeNode = element;
|
||||
}
|
||||
options.droppables.push(e);
|
||||
}, (self.findElements(element, options) || []));
|
||||
|
||||
if (options.tree) {
|
||||
MochiKit.Base.map(function (e) {
|
||||
new MochiKit.DragAndDrop.Droppable(e, options_for_tree);
|
||||
e.treeNode = element;
|
||||
options.droppables.push(e);
|
||||
}, (self.findTreeElements(element, options) || []));
|
||||
}
|
||||
|
||||
// keep reference
|
||||
self.sortables[element.id] = options;
|
||||
|
||||
options.lastValue = self.serialize(element);
|
||||
options.startHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'start',
|
||||
MochiKit.Base.partial(self.onStart, element));
|
||||
options.endHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'end',
|
||||
MochiKit.Base.partial(self.onEnd, element));
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.onStart */
|
||||
onStart: function (element, draggable) {
|
||||
var self = MochiKit.Sortable;
|
||||
var options = self.options(element);
|
||||
options.lastValue = self.serialize(options.element);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.onEnd */
|
||||
onEnd: function (element, draggable) {
|
||||
var self = MochiKit.Sortable;
|
||||
self.unmark();
|
||||
var options = self.options(element);
|
||||
if (options.lastValue != self.serialize(options.element)) {
|
||||
options.onUpdate(options.element);
|
||||
}
|
||||
},
|
||||
|
||||
// return all suitable-for-sortable elements in a guaranteed order
|
||||
|
||||
/** @id MochiKit.Sortable.findElements */
|
||||
findElements: function (element, options) {
|
||||
return MochiKit.Sortable.findChildren(
|
||||
element, options.only, options.tree ? true : false, options.tag);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.findTreeElements */
|
||||
findTreeElements: function (element, options) {
|
||||
return MochiKit.Sortable.findChildren(
|
||||
element, options.only, options.tree ? true : false, options.treeTag);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.findChildren */
|
||||
findChildren: function (element, only, recursive, tagName) {
|
||||
if (!element.hasChildNodes()) {
|
||||
return null;
|
||||
}
|
||||
tagName = tagName.toUpperCase();
|
||||
if (only) {
|
||||
only = MochiKit.Base.flattenArray([only]);
|
||||
}
|
||||
var elements = [];
|
||||
MochiKit.Base.map(function (e) {
|
||||
if (e.tagName &&
|
||||
e.tagName.toUpperCase() == tagName &&
|
||||
(!only ||
|
||||
MochiKit.Iter.some(only, function (c) {
|
||||
return MochiKit.DOM.hasElementClass(e, c);
|
||||
}))) {
|
||||
elements.push(e);
|
||||
}
|
||||
if (recursive) {
|
||||
var grandchildren = MochiKit.Sortable.findChildren(e, only, recursive, tagName);
|
||||
if (grandchildren && grandchildren.length > 0) {
|
||||
elements = elements.concat(grandchildren);
|
||||
}
|
||||
}
|
||||
}, element.childNodes);
|
||||
return elements;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.onHover */
|
||||
onHover: function (element, dropon, overlap) {
|
||||
if (MochiKit.DOM.isParent(dropon, element)) {
|
||||
return;
|
||||
}
|
||||
var self = MochiKit.Sortable;
|
||||
|
||||
if (overlap > .33 && overlap < .66 && self.options(dropon).tree) {
|
||||
return;
|
||||
} else if (overlap > 0.5) {
|
||||
self.mark(dropon, 'before');
|
||||
if (dropon.previousSibling != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = 'hidden'; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, dropon);
|
||||
if (dropon.parentNode != oldParentNode) {
|
||||
self.options(oldParentNode).onChange(element);
|
||||
}
|
||||
self.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
} else {
|
||||
self.mark(dropon, 'after');
|
||||
var nextElement = dropon.nextSibling || null;
|
||||
if (nextElement != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = 'hidden'; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, nextElement);
|
||||
if (dropon.parentNode != oldParentNode) {
|
||||
self.options(oldParentNode).onChange(element);
|
||||
}
|
||||
self.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_offsetSize: function (element, type) {
|
||||
if (type == 'vertical' || type == 'height') {
|
||||
return element.offsetHeight;
|
||||
} else {
|
||||
return element.offsetWidth;
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.onEmptyHover */
|
||||
onEmptyHover: function (element, dropon, overlap) {
|
||||
var oldParentNode = element.parentNode;
|
||||
var self = MochiKit.Sortable;
|
||||
var droponOptions = self.options(dropon);
|
||||
|
||||
if (!MochiKit.DOM.isParent(dropon, element)) {
|
||||
var index;
|
||||
|
||||
var children = self.findElements(dropon, {tag: droponOptions.tag,
|
||||
only: droponOptions.only});
|
||||
var child = null;
|
||||
|
||||
if (children) {
|
||||
var offset = self._offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
|
||||
|
||||
for (index = 0; index < children.length; index += 1) {
|
||||
if (offset - self._offsetSize(children[index], droponOptions.overlap) >= 0) {
|
||||
offset -= self._offsetSize(children[index], droponOptions.overlap);
|
||||
} else if (offset - (self._offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
|
||||
child = index + 1 < children.length ? children[index + 1] : null;
|
||||
break;
|
||||
} else {
|
||||
child = children[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropon.insertBefore(element, child);
|
||||
|
||||
self.options(oldParentNode).onChange(element);
|
||||
droponOptions.onChange(element);
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.unmark */
|
||||
unmark: function () {
|
||||
var m = MochiKit.Sortable._marker;
|
||||
if (m) {
|
||||
MochiKit.Style.hideElement(m);
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.mark */
|
||||
mark: function (dropon, position) {
|
||||
// mark on ghosting only
|
||||
var d = MochiKit.DOM;
|
||||
var self = MochiKit.Sortable;
|
||||
var sortable = self.options(dropon.parentNode);
|
||||
if (sortable && !sortable.ghosting) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self._marker) {
|
||||
self._marker = d.getElement('dropmarker') ||
|
||||
document.createElement('DIV');
|
||||
MochiKit.Style.hideElement(self._marker);
|
||||
d.addElementClass(self._marker, 'dropmarker');
|
||||
self._marker.style.position = 'absolute';
|
||||
document.getElementsByTagName('body').item(0).appendChild(self._marker);
|
||||
}
|
||||
var offsets = MochiKit.Position.cumulativeOffset(dropon);
|
||||
self._marker.style.left = offsets.x + 'px';
|
||||
self._marker.style.top = offsets.y + 'px';
|
||||
|
||||
if (position == 'after') {
|
||||
if (sortable.overlap == 'horizontal') {
|
||||
self._marker.style.left = (offsets.x + dropon.clientWidth) + 'px';
|
||||
} else {
|
||||
self._marker.style.top = (offsets.y + dropon.clientHeight) + 'px';
|
||||
}
|
||||
}
|
||||
MochiKit.Style.showElement(self._marker);
|
||||
},
|
||||
|
||||
_tree: function (element, options, parent) {
|
||||
var self = MochiKit.Sortable;
|
||||
var children = self.findElements(element, options) || [];
|
||||
|
||||
for (var i = 0; i < children.length; ++i) {
|
||||
var match = children[i].id.match(options.format);
|
||||
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var child = {
|
||||
id: encodeURIComponent(match ? match[1] : null),
|
||||
element: element,
|
||||
parent: parent,
|
||||
children: [],
|
||||
position: parent.children.length,
|
||||
container: self._findChildrenElement(children[i], options.treeTag.toUpperCase())
|
||||
}
|
||||
|
||||
/* Get the element containing the children and recurse over it */
|
||||
if (child.container) {
|
||||
self._tree(child.container, options, child)
|
||||
}
|
||||
|
||||
parent.children.push (child);
|
||||
}
|
||||
|
||||
return parent;
|
||||
},
|
||||
|
||||
/* Finds the first element of the given tag type within a parent element.
|
||||
Used for finding the first LI[ST] within a L[IST]I[TEM].*/
|
||||
_findChildrenElement: function (element, containerTag) {
|
||||
if (element && element.hasChildNodes) {
|
||||
containerTag = containerTag.toUpperCase();
|
||||
for (var i = 0; i < element.childNodes.length; ++i) {
|
||||
if (element.childNodes[i].tagName.toUpperCase() == containerTag) {
|
||||
return element.childNodes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.tree */
|
||||
tree: function (element, options) {
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
var sortableOptions = MochiKit.Sortable.options(element);
|
||||
options = MochiKit.Base.update({
|
||||
tag: sortableOptions.tag,
|
||||
treeTag: sortableOptions.treeTag,
|
||||
only: sortableOptions.only,
|
||||
name: element.id,
|
||||
format: sortableOptions.format
|
||||
}, options || {});
|
||||
|
||||
var root = {
|
||||
id: null,
|
||||
parent: null,
|
||||
children: new Array,
|
||||
container: element,
|
||||
position: 0
|
||||
}
|
||||
|
||||
return MochiKit.Sortable._tree(element, options, root);
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies the sequence for the Sortable.
|
||||
* @param {Node} element Element to use as the Sortable.
|
||||
* @param {Object} newSequence New sequence to use.
|
||||
* @param {Object} options Options to use fro the Sortable.
|
||||
*/
|
||||
setSequence: function (element, newSequence, options) {
|
||||
var self = MochiKit.Sortable;
|
||||
var b = MochiKit.Base;
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
options = b.update(self.options(element), options || {});
|
||||
|
||||
var nodeMap = {};
|
||||
b.map(function (n) {
|
||||
var m = n.id.match(options.format);
|
||||
if (m) {
|
||||
nodeMap[m[1]] = [n, n.parentNode];
|
||||
}
|
||||
n.parentNode.removeChild(n);
|
||||
}, self.findElements(element, options));
|
||||
|
||||
b.map(function (ident) {
|
||||
var n = nodeMap[ident];
|
||||
if (n) {
|
||||
n[1].appendChild(n[0]);
|
||||
delete nodeMap[ident];
|
||||
}
|
||||
}, newSequence);
|
||||
},
|
||||
|
||||
/* Construct a [i] index for a particular node */
|
||||
_constructIndex: function (node) {
|
||||
var index = '';
|
||||
do {
|
||||
if (node.id) {
|
||||
index = '[' + node.position + ']' + index;
|
||||
}
|
||||
} while ((node = node.parent) != null);
|
||||
return index;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Sortable.sequence */
|
||||
sequence: function (element, options) {
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
var self = MochiKit.Sortable;
|
||||
var options = MochiKit.Base.update(self.options(element), options || {});
|
||||
|
||||
return MochiKit.Base.map(function (item) {
|
||||
return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
|
||||
}, MochiKit.DOM.getElement(self.findElements(element, options) || []));
|
||||
},
|
||||
|
||||
/**
|
||||
* Serializes the content of a Sortable. Useful to send this content through a XMLHTTPRequest.
|
||||
* These options override the Sortable options for the serialization only.
|
||||
* @param {Node} element Element to serialize.
|
||||
* @param {Object} options Serialization options.
|
||||
*/
|
||||
serialize: function (element, options) {
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
var self = MochiKit.Sortable;
|
||||
options = MochiKit.Base.update(self.options(element), options || {});
|
||||
var name = encodeURIComponent(options.name || element.id);
|
||||
|
||||
if (options.tree) {
|
||||
return MochiKit.Base.flattenArray(MochiKit.Base.map(function (item) {
|
||||
return [name + self._constructIndex(item) + "[id]=" +
|
||||
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
|
||||
}, self.tree(element, options).children)).join('&');
|
||||
} else {
|
||||
return MochiKit.Base.map(function (item) {
|
||||
return name + "[]=" + encodeURIComponent(item);
|
||||
}, self.sequence(element, options)).join('&');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// trunk compatibility
|
||||
MochiKit.Sortable.Sortable = MochiKit.Sortable;
|
|
@ -0,0 +1,445 @@
|
|||
/***
|
||||
|
||||
MochiKit.Style 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005-2006 Bob Ippolito, Beau Hartshorne. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Style');
|
||||
dojo.require('MochiKit.Base');
|
||||
dojo.require('MochiKit.DOM');
|
||||
}
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use('MochiKit.Base', []);
|
||||
JSAN.use('MochiKit.DOM', []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined') {
|
||||
throw '';
|
||||
}
|
||||
} catch (e) {
|
||||
throw 'MochiKit.Style depends on MochiKit.Base!';
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.DOM) == 'undefined') {
|
||||
throw '';
|
||||
}
|
||||
} catch (e) {
|
||||
throw 'MochiKit.Style depends on MochiKit.DOM!';
|
||||
}
|
||||
|
||||
|
||||
if (typeof(MochiKit.Style) == 'undefined') {
|
||||
MochiKit.Style = {};
|
||||
}
|
||||
|
||||
MochiKit.Style.NAME = 'MochiKit.Style';
|
||||
MochiKit.Style.VERSION = '1.4';
|
||||
MochiKit.Style.__repr__ = function () {
|
||||
return '[' + this.NAME + ' ' + this.VERSION + ']';
|
||||
};
|
||||
MochiKit.Style.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
MochiKit.Style.EXPORT_OK = [];
|
||||
|
||||
MochiKit.Style.EXPORT = [
|
||||
'setStyle',
|
||||
'setOpacity',
|
||||
'getStyle',
|
||||
'getElementDimensions',
|
||||
'elementDimensions', // deprecated
|
||||
'setElementDimensions',
|
||||
'getElementPosition',
|
||||
'elementPosition', // deprecated
|
||||
'setElementPosition',
|
||||
'setDisplayForElement',
|
||||
'hideElement',
|
||||
'showElement',
|
||||
'getViewportDimensions',
|
||||
'getViewportPosition',
|
||||
'Dimensions',
|
||||
'Coordinates'
|
||||
];
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Dimensions
|
||||
|
||||
*/
|
||||
/** @id MochiKit.Style.Dimensions */
|
||||
MochiKit.Style.Dimensions = function (w, h) {
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
};
|
||||
|
||||
MochiKit.Style.Dimensions.prototype.__repr__ = function () {
|
||||
var repr = MochiKit.Base.repr;
|
||||
return '{w: ' + repr(this.w) + ', h: ' + repr(this.h) + '}';
|
||||
};
|
||||
|
||||
MochiKit.Style.Dimensions.prototype.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Coordinates
|
||||
|
||||
*/
|
||||
/** @id MochiKit.Style.Coordinates */
|
||||
MochiKit.Style.Coordinates = function (x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
};
|
||||
|
||||
MochiKit.Style.Coordinates.prototype.__repr__ = function () {
|
||||
var repr = MochiKit.Base.repr;
|
||||
return '{x: ' + repr(this.x) + ', y: ' + repr(this.y) + '}';
|
||||
};
|
||||
|
||||
MochiKit.Style.Coordinates.prototype.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
|
||||
MochiKit.Base.update(MochiKit.Style, {
|
||||
|
||||
/** @id MochiKit.Style.getStyle */
|
||||
getStyle: function (elem, cssProperty) {
|
||||
var dom = MochiKit.DOM;
|
||||
var d = dom._document;
|
||||
|
||||
elem = dom.getElement(elem);
|
||||
cssProperty = MochiKit.Base.camelize(cssProperty);
|
||||
|
||||
if (!elem || elem == d) {
|
||||
return undefined;
|
||||
}
|
||||
if (cssProperty == 'opacity' && elem.filters) {
|
||||
var opacity = (MochiKit.Style.getStyle(elem, 'filter') || '').match(/alpha\(opacity=(.*)\)/);
|
||||
if (opacity && opacity[1]) {
|
||||
return parseFloat(opacity[1]) / 100;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
var value = elem.style ? elem.style[cssProperty] : null;
|
||||
if (!value) {
|
||||
if (d.defaultView && d.defaultView.getComputedStyle) {
|
||||
var css = d.defaultView.getComputedStyle(elem, null);
|
||||
cssProperty = cssProperty.replace(/([A-Z])/g, '-$1'
|
||||
).toLowerCase(); // from dojo.style.toSelectorCase
|
||||
value = css ? css.getPropertyValue(cssProperty) : null;
|
||||
} else if (elem.currentStyle) {
|
||||
value = elem.currentStyle[cssProperty];
|
||||
}
|
||||
}
|
||||
if (cssProperty == 'opacity') {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
if (/Opera/.test(navigator.userAgent) && (MochiKit.Base.find(['left', 'top', 'right', 'bottom'], cssProperty) != -1)) {
|
||||
if (MochiKit.Style.getStyle(elem, 'position') == 'static') {
|
||||
value = 'auto';
|
||||
}
|
||||
}
|
||||
|
||||
return value == 'auto' ? null : value;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.setStyle */
|
||||
setStyle: function (elem, style) {
|
||||
elem = MochiKit.DOM.getElement(elem);
|
||||
for (var name in style) {
|
||||
if (name == 'opacity') {
|
||||
MochiKit.Style.setOpacity(elem, style[name]);
|
||||
} else {
|
||||
elem.style[MochiKit.Base.camelize(name)] = style[name];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.setOpacity */
|
||||
setOpacity: function (elem, o) {
|
||||
elem = MochiKit.DOM.getElement(elem);
|
||||
var self = MochiKit.Style;
|
||||
if (o == 1) {
|
||||
var toSet = /Gecko/.test(navigator.userAgent) && !(/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent));
|
||||
elem.style["opacity"] = toSet ? 0.999999 : 1.0;
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
elem.style['filter'] =
|
||||
self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '');
|
||||
}
|
||||
} else {
|
||||
if (o < 0.00001) {
|
||||
o = 0;
|
||||
}
|
||||
elem.style["opacity"] = o;
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
elem.style['filter'] =
|
||||
self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + o * 100 + ')';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
|
||||
getElementPosition is adapted from YAHOO.util.Dom.getXY v0.9.0.
|
||||
Copyright: Copyright (c) 2006, Yahoo! Inc. All rights reserved.
|
||||
License: BSD, http://developer.yahoo.net/yui/license.txt
|
||||
|
||||
*/
|
||||
|
||||
/** @id MochiKit.Style.getElementPosition */
|
||||
getElementPosition: function (elem, /* optional */relativeTo) {
|
||||
var self = MochiKit.Style;
|
||||
var dom = MochiKit.DOM;
|
||||
elem = dom.getElement(elem);
|
||||
|
||||
if (!elem ||
|
||||
(!(elem.x && elem.y) &&
|
||||
(!elem.parentNode === null ||
|
||||
self.getStyle(elem, 'display') == 'none'))) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var c = new self.Coordinates(0, 0);
|
||||
var box = null;
|
||||
var parent = null;
|
||||
|
||||
var d = MochiKit.DOM._document;
|
||||
var de = d.documentElement;
|
||||
var b = d.body;
|
||||
|
||||
if (!elem.parentNode && elem.x && elem.y) {
|
||||
/* it's just a MochiKit.Style.Coordinates object */
|
||||
c.x += elem.x || 0;
|
||||
c.y += elem.y || 0;
|
||||
} else if (elem.getBoundingClientRect) { // IE shortcut
|
||||
/*
|
||||
|
||||
The IE shortcut can be off by two. We fix it. See:
|
||||
http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
|
||||
|
||||
This is similar to the method used in
|
||||
MochiKit.Signal.Event.mouse().
|
||||
|
||||
*/
|
||||
box = elem.getBoundingClientRect();
|
||||
|
||||
c.x += box.left +
|
||||
(de.scrollLeft || b.scrollLeft) -
|
||||
(de.clientLeft || 0);
|
||||
|
||||
c.y += box.top +
|
||||
(de.scrollTop || b.scrollTop) -
|
||||
(de.clientTop || 0);
|
||||
|
||||
} else if (elem.offsetParent) {
|
||||
c.x += elem.offsetLeft;
|
||||
c.y += elem.offsetTop;
|
||||
parent = elem.offsetParent;
|
||||
|
||||
if (parent != elem) {
|
||||
while (parent) {
|
||||
c.x += parent.offsetLeft;
|
||||
c.y += parent.offsetTop;
|
||||
parent = parent.offsetParent;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Opera < 9 and old Safari (absolute) incorrectly account for
|
||||
body offsetTop and offsetLeft.
|
||||
|
||||
*/
|
||||
var ua = navigator.userAgent.toLowerCase();
|
||||
if ((typeof(opera) != 'undefined' &&
|
||||
parseFloat(opera.version()) < 9) ||
|
||||
(ua.indexOf('AppleWebKit') != -1 &&
|
||||
self.getStyle(elem, 'position') == 'absolute')) {
|
||||
|
||||
c.x -= b.offsetLeft;
|
||||
c.y -= b.offsetTop;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof(relativeTo) != 'undefined') {
|
||||
relativeTo = arguments.callee(relativeTo);
|
||||
if (relativeTo) {
|
||||
c.x -= (relativeTo.x || 0);
|
||||
c.y -= (relativeTo.y || 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (elem.parentNode) {
|
||||
parent = elem.parentNode;
|
||||
} else {
|
||||
parent = null;
|
||||
}
|
||||
|
||||
while (parent) {
|
||||
var tagName = parent.tagName.toUpperCase();
|
||||
if (tagName === 'BODY' || tagName === 'HTML') {
|
||||
break;
|
||||
}
|
||||
var disp = self.getStyle(parent, 'display');
|
||||
// Handle strange Opera bug for some display
|
||||
if (disp != 'inline' && disp != 'table-row') {
|
||||
c.x -= parent.scrollLeft;
|
||||
c.y -= parent.scrollTop;
|
||||
}
|
||||
if (parent.parentNode) {
|
||||
parent = parent.parentNode;
|
||||
} else {
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.setElementPosition */
|
||||
setElementPosition: function (elem, newPos/* optional */, units) {
|
||||
elem = MochiKit.DOM.getElement(elem);
|
||||
if (typeof(units) == 'undefined') {
|
||||
units = 'px';
|
||||
}
|
||||
var newStyle = {};
|
||||
var isUndefNull = MochiKit.Base.isUndefinedOrNull;
|
||||
if (!isUndefNull(newPos.x)) {
|
||||
newStyle['left'] = newPos.x + units;
|
||||
}
|
||||
if (!isUndefNull(newPos.y)) {
|
||||
newStyle['top'] = newPos.y + units;
|
||||
}
|
||||
MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.getElementDimensions */
|
||||
getElementDimensions: function (elem) {
|
||||
var self = MochiKit.Style;
|
||||
var dom = MochiKit.DOM;
|
||||
if (typeof(elem.w) == 'number' || typeof(elem.h) == 'number') {
|
||||
return new self.Dimensions(elem.w || 0, elem.h || 0);
|
||||
}
|
||||
elem = dom.getElement(elem);
|
||||
if (!elem) {
|
||||
return undefined;
|
||||
}
|
||||
var disp = self.getStyle(elem, 'display');
|
||||
// display can be empty/undefined on WebKit/KHTML
|
||||
if (disp != 'none' && disp !== '' && typeof(disp) != 'undefined') {
|
||||
return new self.Dimensions(elem.offsetWidth || 0,
|
||||
elem.offsetHeight || 0);
|
||||
}
|
||||
var s = elem.style;
|
||||
var originalVisibility = s.visibility;
|
||||
var originalPosition = s.position;
|
||||
s.visibility = 'hidden';
|
||||
s.position = 'absolute';
|
||||
s.display = '';
|
||||
var originalWidth = elem.offsetWidth;
|
||||
var originalHeight = elem.offsetHeight;
|
||||
s.display = 'none';
|
||||
s.position = originalPosition;
|
||||
s.visibility = originalVisibility;
|
||||
return new self.Dimensions(originalWidth, originalHeight);
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.setElementDimensions */
|
||||
setElementDimensions: function (elem, newSize/* optional */, units) {
|
||||
elem = MochiKit.DOM.getElement(elem);
|
||||
if (typeof(units) == 'undefined') {
|
||||
units = 'px';
|
||||
}
|
||||
var newStyle = {};
|
||||
var isUndefNull = MochiKit.Base.isUndefinedOrNull;
|
||||
if (!isUndefNull(newSize.w)) {
|
||||
newStyle['width'] = newSize.w + units;
|
||||
}
|
||||
if (!isUndefNull(newSize.h)) {
|
||||
newStyle['height'] = newSize.h + units;
|
||||
}
|
||||
MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.setDisplayForElement */
|
||||
setDisplayForElement: function (display, element/*, ...*/) {
|
||||
var elements = MochiKit.Base.extend(null, arguments, 1);
|
||||
var getElement = MochiKit.DOM.getElement;
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
element = getElement(elements[i]);
|
||||
if (element) {
|
||||
element.style.display = display;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.getViewportDimensions */
|
||||
getViewportDimensions: function () {
|
||||
var d = new MochiKit.Style.Dimensions();
|
||||
|
||||
var w = MochiKit.DOM._window;
|
||||
var b = MochiKit.DOM._document.body;
|
||||
|
||||
if (w.innerWidth) {
|
||||
d.w = w.innerWidth;
|
||||
d.h = w.innerHeight;
|
||||
} else if (b.parentElement.clientWidth) {
|
||||
d.w = b.parentElement.clientWidth;
|
||||
d.h = b.parentElement.clientHeight;
|
||||
} else if (b && b.clientWidth) {
|
||||
d.w = b.clientWidth;
|
||||
d.h = b.clientHeight;
|
||||
}
|
||||
return d;
|
||||
},
|
||||
|
||||
/** @id MochiKit.Style.getViewportPosition */
|
||||
getViewportPosition: function () {
|
||||
var c = new MochiKit.Style.Coordinates(0, 0);
|
||||
var d = MochiKit.DOM._document;
|
||||
var de = d.documentElement;
|
||||
var db = d.body;
|
||||
if (de && (de.scrollTop || de.scrollLeft)) {
|
||||
c.x = de.scrollLeft;
|
||||
c.y = de.scrollTop;
|
||||
} else if (db) {
|
||||
c.x = db.scrollLeft;
|
||||
c.y = db.scrollTop;
|
||||
}
|
||||
return c;
|
||||
},
|
||||
|
||||
__new__: function () {
|
||||
var m = MochiKit.Base;
|
||||
|
||||
this.elementPosition = this.getElementPosition;
|
||||
this.elementDimensions = this.getElementDimensions;
|
||||
|
||||
this.hideElement = m.partial(this.setDisplayForElement, 'none');
|
||||
this.showElement = m.partial(this.setDisplayForElement, 'block');
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
':common': this.EXPORT,
|
||||
':all': m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
}
|
||||
});
|
||||
|
||||
MochiKit.Style.__new__();
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Style);
|
|
@ -0,0 +1,181 @@
|
|||
/***
|
||||
|
||||
MochiKit.Test 1.4
|
||||
|
||||
See <http://mochikit.com/> for documentation, downloads, license, etc.
|
||||
|
||||
(c) 2005 Bob Ippolito. All rights Reserved.
|
||||
|
||||
***/
|
||||
|
||||
if (typeof(dojo) != 'undefined') {
|
||||
dojo.provide('MochiKit.Test');
|
||||
dojo.require('MochiKit.Base');
|
||||
}
|
||||
|
||||
if (typeof(JSAN) != 'undefined') {
|
||||
JSAN.use("MochiKit.Base", []);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof(MochiKit.Base) == 'undefined') {
|
||||
throw "";
|
||||
}
|
||||
} catch (e) {
|
||||
throw "MochiKit.Test depends on MochiKit.Base!";
|
||||
}
|
||||
|
||||
if (typeof(MochiKit.Test) == 'undefined') {
|
||||
MochiKit.Test = {};
|
||||
}
|
||||
|
||||
MochiKit.Test.NAME = "MochiKit.Test";
|
||||
MochiKit.Test.VERSION = "1.4";
|
||||
MochiKit.Test.__repr__ = function () {
|
||||
return "[" + this.NAME + " " + this.VERSION + "]";
|
||||
};
|
||||
|
||||
MochiKit.Test.toString = function () {
|
||||
return this.__repr__();
|
||||
};
|
||||
|
||||
|
||||
MochiKit.Test.EXPORT = ["runTests"];
|
||||
MochiKit.Test.EXPORT_OK = [];
|
||||
|
||||
MochiKit.Test.runTests = function (obj) {
|
||||
if (typeof(obj) == "string") {
|
||||
obj = JSAN.use(obj);
|
||||
}
|
||||
var suite = new MochiKit.Test.Suite();
|
||||
suite.run(obj);
|
||||
};
|
||||
|
||||
MochiKit.Test.Suite = function () {
|
||||
this.testIndex = 0;
|
||||
MochiKit.Base.bindMethods(this);
|
||||
};
|
||||
|
||||
MochiKit.Test.Suite.prototype = {
|
||||
run: function (obj) {
|
||||
try {
|
||||
obj(this);
|
||||
} catch (e) {
|
||||
this.traceback(e);
|
||||
}
|
||||
},
|
||||
traceback: function (e) {
|
||||
var items = MochiKit.Iter.sorted(MochiKit.Base.items(e));
|
||||
print("not ok " + this.testIndex + " - Error thrown");
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var kv = items[i];
|
||||
if (kv[0] == "stack") {
|
||||
kv[1] = kv[1].split(/\n/)[0];
|
||||
}
|
||||
this.print("# " + kv.join(": "));
|
||||
}
|
||||
},
|
||||
print: function (s) {
|
||||
print(s);
|
||||
},
|
||||
is: function (got, expected, /* optional */message) {
|
||||
var res = 1;
|
||||
var msg = null;
|
||||
try {
|
||||
res = MochiKit.Base.compare(got, expected);
|
||||
} catch (e) {
|
||||
msg = "Can not compare " + typeof(got) + ":" + typeof(expected);
|
||||
}
|
||||
if (res) {
|
||||
msg = "Expected value did not compare equal";
|
||||
}
|
||||
if (!res) {
|
||||
return this.testResult(true, message);
|
||||
}
|
||||
return this.testResult(false, message,
|
||||
[[msg], ["got:", got], ["expected:", expected]]);
|
||||
},
|
||||
|
||||
testResult: function (pass, msg, failures) {
|
||||
this.testIndex += 1;
|
||||
if (pass) {
|
||||
this.print("ok " + this.testIndex + " - " + msg);
|
||||
return;
|
||||
}
|
||||
this.print("not ok " + this.testIndex + " - " + msg);
|
||||
if (failures) {
|
||||
for (var i = 0; i < failures.length; i++) {
|
||||
this.print("# " + failures[i].join(" "));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isDeeply: function (got, expected, /* optional */message) {
|
||||
var m = MochiKit.Base;
|
||||
var res = 1;
|
||||
try {
|
||||
res = m.compare(got, expected);
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
if (res === 0) {
|
||||
return this.ok(true, message);
|
||||
}
|
||||
var gk = m.keys(got);
|
||||
var ek = m.keys(expected);
|
||||
gk.sort();
|
||||
ek.sort();
|
||||
if (m.compare(gk, ek)) {
|
||||
// differing keys
|
||||
var cmp = {};
|
||||
var i;
|
||||
for (i = 0; i < gk.length; i++) {
|
||||
cmp[gk[i]] = "got";
|
||||
}
|
||||
for (i = 0; i < ek.length; i++) {
|
||||
if (ek[i] in cmp) {
|
||||
delete cmp[ek[i]];
|
||||
} else {
|
||||
cmp[ek[i]] = "expected";
|
||||
}
|
||||
}
|
||||
var diffkeys = m.keys(cmp);
|
||||
diffkeys.sort();
|
||||
var gotkeys = [];
|
||||
var expkeys = [];
|
||||
while (diffkeys.length) {
|
||||
var k = diffkeys.shift();
|
||||
if (k in Object.prototype) {
|
||||
continue;
|
||||
}
|
||||
(cmp[k] == "got" ? gotkeys : expkeys).push(k);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return this.testResult((!res), msg,
|
||||
(msg ? [["got:", got], ["expected:", expected]] : undefined)
|
||||
);
|
||||
},
|
||||
|
||||
ok: function (res, message) {
|
||||
return this.testResult(res, message);
|
||||
}
|
||||
};
|
||||
|
||||
MochiKit.Test.__new__ = function () {
|
||||
var m = MochiKit.Base;
|
||||
|
||||
this.EXPORT_TAGS = {
|
||||
":common": this.EXPORT,
|
||||
":all": m.concat(this.EXPORT, this.EXPORT_OK)
|
||||
};
|
||||
|
||||
m.nameFunctions(this);
|
||||
|
||||
};
|
||||
|
||||
MochiKit.Test.__new__();
|
||||
|
||||
MochiKit.Base._exportSymbols(this, MochiKit.Test);
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,18 @@
|
|||
dojo.kwCompoundRequire({
|
||||
"common": [
|
||||
"MochiKit.Base",
|
||||
"MochiKit.Iter",
|
||||
"MochiKit.Logging",
|
||||
"MochiKit.DateTime",
|
||||
"MochiKit.Format",
|
||||
"MochiKit.Async",
|
||||
"MochiKit.DOM",
|
||||
"MochiKit.Style",
|
||||
"MochiKit.LoggingPane",
|
||||
"MochiKit.Color",
|
||||
"MochiKit.Signal",
|
||||
"MochiKit.Position",
|
||||
"MochiKit.Visual"
|
||||
]
|
||||
});
|
||||
dojo.provide("MochiKit.*");
|
|
@ -0,0 +1 @@
|
|||
{testcases:["tests/index.html"]}
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Mochikit</title>
|
||||
<script type="text/javascript" src="../lib/MochiKit_packed.js"></script>
|
||||
<script type="text/javascript" src="../lib/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="../lib/AJAX_setup.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../lib/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe width="100%" height="500" id="testframe" src=""></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
var JSAN = {
|
||||
global: this,
|
||||
use: function (module, symbols) {
|
||||
var components = module.split(/\./);
|
||||
var fn = components.join('/') + '.js';
|
||||
var o = JSAN.global;
|
||||
var i, c;
|
||||
for (i = 0; i < components.length; i++) {
|
||||
o = o[components[i]];
|
||||
if (typeof(o) == 'undefined') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (typeof(o) != 'undefined') {
|
||||
return o;
|
||||
}
|
||||
|
||||
load(fn);
|
||||
o = JSAN.global;
|
||||
for (i = 0; i < components.length; i++) {
|
||||
o = o[components[i]];
|
||||
if (typeof(o) == 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (!symbols) {
|
||||
var tags = o.EXPORT_TAGS;
|
||||
if (tags) {
|
||||
symbols = tags[':common'] || tags[':all'];
|
||||
}
|
||||
}
|
||||
if (symbols) {
|
||||
for (i = 0; i < symbols.length; i++) {
|
||||
c = symbols[i];
|
||||
JSAN.global[c] = o[c];
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,84 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/ajax/mochikit/tests
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = \
|
||||
SimpleTest \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
FakeJSAN.js \
|
||||
cli.js \
|
||||
index.html \
|
||||
standalone.js \
|
||||
test_Base.js \
|
||||
test_Color.js \
|
||||
test_DateTime.js \
|
||||
test_DragAndDrop.js \
|
||||
test_Format.js \
|
||||
test_Iter.js \
|
||||
test_Logging.js \
|
||||
test_MochiKit-Async.json \
|
||||
MochiKit-Async.html \
|
||||
MochiKit-Base.html \
|
||||
MochiKit-Color.html \
|
||||
MochiKit-DOM.html \
|
||||
MochiKit-DateTime.html \
|
||||
MochiKit-DragAndDrop.html \
|
||||
MochiKit-Format.html \
|
||||
MochiKit-Iter.html \
|
||||
MochiKit-JSAN.html \
|
||||
MochiKit-Logging.html \
|
||||
MochiKit-MochiKit.html \
|
||||
MochiKit-Selector.html \
|
||||
MochiKit-Signal.html \
|
||||
MochiKit-Style.html \
|
||||
MochiKit-Visual.html \
|
||||
test_Signal.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
|
@ -0,0 +1,408 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Async.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
var increment = function (res) {
|
||||
return res + 1;
|
||||
}
|
||||
|
||||
var throwStuff = function (res) {
|
||||
throw new GenericError(res);
|
||||
}
|
||||
|
||||
var catchStuff = function (res) {
|
||||
return res.message;
|
||||
}
|
||||
|
||||
var returnError = function (res) {
|
||||
return new GenericError(res);
|
||||
}
|
||||
|
||||
var anythingOkCallback = function (msg) {
|
||||
return function (res) {
|
||||
ok(true, msg);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
var testEqCallback = function () {
|
||||
/*
|
||||
sort of emulate how deferreds work in Twisted
|
||||
for "convenient" testing
|
||||
*/
|
||||
var args = [];
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
return function (res) {
|
||||
var nargs = args.slice();
|
||||
nargs.unshift(res);
|
||||
is.apply(this, nargs);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
var neverHappen = function (d) {
|
||||
ok(false, "this should never happen");
|
||||
}
|
||||
|
||||
/*
|
||||
Test normal Deferred operation
|
||||
*/
|
||||
var d = new Deferred();
|
||||
d.addCallback(testEqCallback(1, "pre-deferred callback"));
|
||||
d.callback(1);
|
||||
d.addCallback(increment);
|
||||
d.addCallback(testEqCallback(2, "post-deferred callback"));
|
||||
d.addCallback(throwStuff);
|
||||
d.addCallback(neverHappen);
|
||||
d.addErrback(catchStuff);
|
||||
d.addCallback(testEqCallback(2, "throw -> err, catch -> success"));
|
||||
d.addCallback(returnError);
|
||||
d.addCallback(neverHappen);
|
||||
d.addErrback(catchStuff);
|
||||
d.addCallback(testEqCallback(2, "return -> err, catch -> succcess"));
|
||||
|
||||
/*
|
||||
Test Deferred cancellation
|
||||
*/
|
||||
var cancelled = function (d) {
|
||||
ok(true, "canceller called!");
|
||||
}
|
||||
|
||||
var cancelledError = function (res) {
|
||||
ok(res instanceof CancelledError, "CancelledError here");
|
||||
}
|
||||
|
||||
d = new Deferred(cancelled);
|
||||
d.addCallback(neverHappen);
|
||||
d.addErrback(cancelledError);
|
||||
d.cancel();
|
||||
|
||||
/*
|
||||
Test succeed / fail
|
||||
*/
|
||||
|
||||
d = succeed(1).addCallback(testEqCallback(1, "succeed"));
|
||||
|
||||
// default error
|
||||
d = fail().addCallback(neverHappen);
|
||||
d = d.addErrback(anythingOkCallback("default fail"));
|
||||
|
||||
// default wrapped error
|
||||
d = fail("web taco").addCallback(neverHappen).addErrback(catchStuff);
|
||||
d = d.addCallback(testEqCallback("web taco", "wrapped fail"));
|
||||
|
||||
// default unwrapped error
|
||||
d = fail(new GenericError("ugh")).addCallback(neverHappen).addErrback(catchStuff);
|
||||
d = d.addCallback(testEqCallback("ugh", "unwrapped fail"));
|
||||
|
||||
/*
|
||||
Test deferred dependencies
|
||||
*/
|
||||
|
||||
var deferredIncrement = function (res) {
|
||||
var rval = succeed(res);
|
||||
rval.addCallback(increment);
|
||||
return rval;
|
||||
}
|
||||
|
||||
d = succeed(1).addCallback(deferredIncrement);
|
||||
d = d.addCallback(testEqCallback(2, "dependent deferred succeed"));
|
||||
|
||||
var deferredFailure = function (res) {
|
||||
return fail(res);
|
||||
}
|
||||
|
||||
d = succeed("ugh").addCallback(deferredFailure).addErrback(catchStuff);
|
||||
d = d.addCallback(testEqCallback("ugh", "dependent deferred fail"));
|
||||
|
||||
/*
|
||||
Test double-calling, double-failing, etc.
|
||||
*/
|
||||
try {
|
||||
succeed(1).callback(2);
|
||||
neverHappen();
|
||||
} catch (e) {
|
||||
ok(e instanceof AlreadyCalledError, "double-call");
|
||||
}
|
||||
try {
|
||||
fail(1).errback(2);
|
||||
neverHappen();
|
||||
} catch (e) {
|
||||
ok(e instanceof AlreadyCalledError, "double-fail");
|
||||
}
|
||||
try {
|
||||
d = succeed(1);
|
||||
d.cancel();
|
||||
d = d.callback(2);
|
||||
ok(true, "swallowed one callback, no canceller");
|
||||
d.callback(3);
|
||||
neverHappen();
|
||||
} catch (e) {
|
||||
ok(e instanceof AlreadyCalledError, "swallow cancel");
|
||||
}
|
||||
try {
|
||||
d = new Deferred(cancelled);
|
||||
d.cancel();
|
||||
d = d.callback(1);
|
||||
neverHappen();
|
||||
} catch (e) {
|
||||
ok(e instanceof AlreadyCalledError, "non-swallowed cancel");
|
||||
}
|
||||
|
||||
/* Test incorrect Deferred usage */
|
||||
|
||||
d = new Deferred();
|
||||
try {
|
||||
d.callback(new Deferred());
|
||||
neverHappen();
|
||||
} catch (e) {
|
||||
ok (e instanceof Error, "deferred not allowed for callback");
|
||||
}
|
||||
d = new Deferred();
|
||||
try {
|
||||
d.errback(new Deferred());
|
||||
neverHappen();
|
||||
} catch (e) {
|
||||
ok (e instanceof Error, "deferred not allowed for errback");
|
||||
}
|
||||
|
||||
d = new Deferred();
|
||||
(new Deferred()).addCallback(function () { return d; }).callback(1);
|
||||
try {
|
||||
d.addCallback(function () {});
|
||||
neverHappen();
|
||||
} catch (e) {
|
||||
ok (e instanceof Error, "chained deferred not allowed to be re-used");
|
||||
}
|
||||
|
||||
/*
|
||||
evalJSONRequest test
|
||||
*/
|
||||
var fakeReq = {"responseText":'[1,2,3,4,"asdf",{"a":["b", "c"]}]'};
|
||||
var obj = [1,2,3,4,"asdf",{"a":["b", "c"]}];
|
||||
isDeeply(obj, evalJSONRequest(fakeReq), "evalJSONRequest");
|
||||
|
||||
try {
|
||||
MochiKit.Async.getXMLHttpRequest();
|
||||
ok(true, "getXMLHttpRequest");
|
||||
} catch (e) {
|
||||
ok(false, "no love from getXMLHttpRequest");
|
||||
}
|
||||
|
||||
var lock = new DeferredLock();
|
||||
var lst = [];
|
||||
var pushNumber = function (x) {
|
||||
return function (res) { lst.push(x); }
|
||||
};
|
||||
lock.acquire().addCallback(pushNumber(1));
|
||||
is( compare(lst, [1]), 0, "lock acquired" );
|
||||
lock.acquire().addCallback(pushNumber(2));
|
||||
is( compare(lst, [1]), 0, "lock waiting for release" );
|
||||
lock.acquire().addCallback(pushNumber(3));
|
||||
is( compare(lst, [1]), 0, "lock waiting for release" );
|
||||
lock.release();
|
||||
is( compare(lst, [1, 2]), 0, "lock passed on" );
|
||||
lock.release();
|
||||
is( compare(lst, [1, 2, 3]), 0, "lock passed on" );
|
||||
lock.release();
|
||||
try {
|
||||
lock.release();
|
||||
ok( false, "over-release didn't raise" );
|
||||
} catch (e) {
|
||||
ok( true, "over-release raised" );
|
||||
}
|
||||
lock.acquire().addCallback(pushNumber(1));
|
||||
is( compare(lst, [1, 2, 3, 1]), 0, "lock acquired" );
|
||||
lock.release();
|
||||
is( compare(lst, [1, 2, 3, 1]), 0, "lock released" );
|
||||
|
||||
var d = new Deferred();
|
||||
lst = [];
|
||||
d.addCallback(operator.add, 2);
|
||||
d.addBoth(operator.add, 4);
|
||||
d.addCallback(bind(lst.push, lst));
|
||||
d.callback(1);
|
||||
is( lst[0], 7, "auto-partial addCallback addBoth" );
|
||||
d.addCallback(function () { throw new Error(); });
|
||||
ebTest = function(a, b) {
|
||||
map(bind(lst.push, lst), arguments);
|
||||
};
|
||||
d.addErrback(ebTest, "foo");
|
||||
is( lst[1], "foo", "auto-partial errback" );
|
||||
is( lst.length, 3, "auto-partial errback" );
|
||||
|
||||
/*
|
||||
Test DeferredList
|
||||
*/
|
||||
|
||||
var callList = [new Deferred(), new Deferred(), new Deferred()];
|
||||
callList[0].addCallback(increment);
|
||||
callList[1].addCallback(increment);
|
||||
callList[2].addCallback(increment);
|
||||
var defList = new DeferredList(callList);
|
||||
ok(defList instanceof Deferred, "DeferredList looks like a Deferred");
|
||||
|
||||
callList[0].callback(3);
|
||||
callList[1].callback(5);
|
||||
callList[2].callback(4);
|
||||
|
||||
defList.addCallback(function (lst) {
|
||||
is( arrayEqual(lst, [[true, 4], [true, 6], [true, 5]]), 1,
|
||||
"deferredlist result ok" );
|
||||
});
|
||||
|
||||
/*
|
||||
Test fireOnOneCallback
|
||||
*/
|
||||
|
||||
var callList2 = [new Deferred(), new Deferred(), new Deferred()];
|
||||
callList2[0].addCallback(increment);
|
||||
callList2[1].addCallback(increment);
|
||||
callList2[2].addCallback(increment);
|
||||
var defList2 = new DeferredList(callList2, true);
|
||||
callList2[1].callback(5);
|
||||
callList2[0].callback(3);
|
||||
callList2[2].callback(4);
|
||||
|
||||
defList2.addCallback(function (lst) {
|
||||
is( arrayEqual(lst, [1, 6]), 1, "deferredlist fireOnOneCallback ok" );
|
||||
});
|
||||
|
||||
/*
|
||||
Test fireOnOneErrback
|
||||
*/
|
||||
|
||||
var callList3 = [new Deferred(), new Deferred(), new Deferred()];
|
||||
callList3[0].addCallback(increment);
|
||||
callList3[1].addCallback(throwStuff);
|
||||
callList3[2].addCallback(increment);
|
||||
var defList3 = new DeferredList(callList3, false, true);
|
||||
defList3.callback = neverHappen;
|
||||
callList3[0].callback(3);
|
||||
callList3[1].callback("foo");
|
||||
callList3[2].callback(4);
|
||||
|
||||
defList3.addErrback(function (err) {
|
||||
is( err.message, "foo", "deferredlist fireOnOneErrback ok" );
|
||||
});
|
||||
|
||||
/*
|
||||
Test consumeErrors
|
||||
*/
|
||||
|
||||
var callList4 = [new Deferred(), new Deferred(), new Deferred()];
|
||||
callList4[0].addCallback(increment);
|
||||
callList4[1].addCallback(throwStuff);
|
||||
callList4[2].addCallback(increment);
|
||||
var defList4 = new DeferredList(callList4, false, false, true);
|
||||
defList4.addErrback(neverHappen);
|
||||
callList4[1].addCallback(function (arg) {
|
||||
is(arg, null, "deferredlist consumeErrors ok" );
|
||||
});
|
||||
callList4[0].callback(3);
|
||||
callList4[1].callback("foo");
|
||||
callList4[2].callback(4);
|
||||
|
||||
/*
|
||||
Test gatherResults
|
||||
*/
|
||||
|
||||
var callList5 = [new Deferred(), new Deferred(), new Deferred()];
|
||||
callList5[0].addCallback(increment);
|
||||
callList5[1].addCallback(increment);
|
||||
callList5[2].addCallback(increment);
|
||||
var gatherRet = gatherResults(callList5);
|
||||
callList5[0].callback(3);
|
||||
callList5[1].callback(5);
|
||||
callList5[2].callback(4);
|
||||
|
||||
gatherRet.addCallback(function (lst) {
|
||||
is( arrayEqual(lst, [4, 6, 5]), 1,
|
||||
"gatherResults result ok" );
|
||||
});
|
||||
|
||||
/*
|
||||
Test maybeDeferred
|
||||
*/
|
||||
|
||||
var maybeDef = maybeDeferred(increment, 4);
|
||||
maybeDef.addCallback(testEqCallback(5, "maybeDeferred sync ok"));
|
||||
|
||||
var maybeDef2 = deferredIncrement(8);
|
||||
maybeDef2.addCallback(testEqCallback(9, "maybeDeferred async ok"));
|
||||
|
||||
ok( true, "synchronous test suite finished!");
|
||||
|
||||
var t = (new Date().getTime());
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
checkCallLater = function (originalTime) {
|
||||
is(originalTime, t, "argument passed in OK");
|
||||
is(arguments.length, 1, "argument count right");
|
||||
};
|
||||
var lock = new DeferredLock();
|
||||
withLock = function (msg) {
|
||||
var cb = partial.apply(null, extend(null, arguments, 1));
|
||||
var d = lock.acquire().addCallback(cb);
|
||||
d.addErrback(ok, false, msg);
|
||||
d.addCallback(function () {
|
||||
ok(true, msg);
|
||||
lock.release();
|
||||
});
|
||||
return d;
|
||||
}
|
||||
withLock("callLater", function () {
|
||||
return callLater(0.05, checkCallLater, t);
|
||||
});
|
||||
withLock("wait", function () {
|
||||
return wait(0.05, t).addCallback(checkCallLater);
|
||||
});
|
||||
withLock("loadJSONDoc", function () {
|
||||
var d = loadJSONDoc("test_MochiKit-Async.json");
|
||||
d.addCallback(function (doc) {
|
||||
is(doc.passed, true, "loadJSONDoc passed");
|
||||
});
|
||||
d.addErrback(function (doc) {
|
||||
ok(false, "loadJSONDoc failed");
|
||||
});
|
||||
return d;
|
||||
});
|
||||
lock.acquire().addCallback(function () {
|
||||
ok(true, "async suite finished");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
SimpleTest.finish();
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,34 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_Base.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
tests.test_Base({ok:ok,is:is});
|
||||
ok( true, "test suite finished!");
|
||||
} catch (err) {
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,84 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Logging.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Color.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
<style type="text/css">.redtext {color: red}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="position:absolute; top: 0px; left:0px; width:0px; height:0px">
|
||||
<span style="color: red" id="c_direct"></span>
|
||||
<span class="redtext" id="c_indirect"></span>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_Color.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
var t = {ok:ok, is:is};
|
||||
tests.test_Color({ok:ok, is:is});
|
||||
is(
|
||||
Color.fromText(SPAN()).toHexString(),
|
||||
"#000000",
|
||||
"fromText no style"
|
||||
);
|
||||
|
||||
is(
|
||||
Color.fromText("c_direct").toHexString(),
|
||||
Color.fromName("red").toHexString(),
|
||||
"fromText direct style"
|
||||
);
|
||||
|
||||
is(
|
||||
Color.fromText("c_indirect").toHexString(),
|
||||
Color.fromName("red").toHexString(),
|
||||
"fromText indirect style"
|
||||
);
|
||||
|
||||
is(
|
||||
Color.fromComputedStyle("c_direct", "color").toHexString(),
|
||||
Color.fromName("red").toHexString(),
|
||||
"fromComputedStyle direct style"
|
||||
);
|
||||
|
||||
is(
|
||||
Color.fromComputedStyle("c_indirect", "color").toHexString(),
|
||||
Color.fromName("red").toHexString(),
|
||||
"fromComputedStyle indirect style"
|
||||
);
|
||||
|
||||
is(
|
||||
Color.fromBackground((SPAN(null, 'test'))).toHexString(),
|
||||
Color.fromName("white").toHexString(),
|
||||
"fromBackground with DOM"
|
||||
);
|
||||
|
||||
|
||||
// Done!
|
||||
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,316 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/MockDOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="display: none;">
|
||||
<form id="form_test">
|
||||
<select name="select">
|
||||
<option value="foo" selected="selected">foo</option>
|
||||
<option value="bar">bar</option>
|
||||
<option value="baz">baz</option>
|
||||
</select>
|
||||
<select name="selmultiple" multiple="multiple">
|
||||
<option value="bar" selected="selected">bar</option>
|
||||
<option value="baz" selected="selected">baz</option>
|
||||
<option value="foo">foo</option>
|
||||
</select>
|
||||
<input type="hidden" name="hidden" value="test" />
|
||||
<input type="radio" name="radio_off" value="1" />
|
||||
<input type="radio" name="radio_off" value="2" />
|
||||
<input type="radio" name="radio_off" value="3" />
|
||||
<input type="radio" name="radio_on" value="1" />
|
||||
<input type="radio" name="radio_on" value="2" checked="checked" />
|
||||
<input type="radio" name="radio_on" value="3" />
|
||||
</form>
|
||||
<form id="form_test2">
|
||||
<select name="selempty">
|
||||
<option value="" selected="selected">foo</option>
|
||||
</select>
|
||||
<select name="selempty2">
|
||||
<option selected="selected">foo</option>
|
||||
</select>
|
||||
</form>
|
||||
<div id="parentTwo" class="two">
|
||||
<div id="parentOne" class="one">
|
||||
<div id="parentZero" class="zero">
|
||||
<span id="child">child</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
lst = [];
|
||||
o = {"blah": function () { lst.push("original"); }};
|
||||
addToCallStack(o, "blah", function () { lst.push("new"); }, true);
|
||||
addToCallStack(o, "blah", function () { lst.push("stuff"); }, true);
|
||||
is( typeof(o.blah), 'function', 'addToCallStack has a function' );
|
||||
is( o.blah.callStack.length, 3, 'callStack length 3' );
|
||||
o.blah();
|
||||
is( lst.join(" "), "original new stuff", "callStack in correct order" );
|
||||
is( o.blah, null, "set to null" );
|
||||
lst = [];
|
||||
o = {"blah": function () { lst.push("original"); }};
|
||||
addToCallStack(o, "blah",
|
||||
function () { lst.push("new"); return false;}, false);
|
||||
addToCallStack(o, "blah", function () { lst.push("stuff"); }, false);
|
||||
o.blah();
|
||||
is( lst.join(" "), "original new", "callStack in correct order (abort)" );
|
||||
o.blah();
|
||||
is( lst.join(" "), "original new original new", "callStack in correct order (again)" );
|
||||
|
||||
|
||||
is( escapeHTML("<>\"&bar"), "<>"&bar", "escapeHTML" ); // for emacs highlighting: "
|
||||
|
||||
var isDOM = function (value, expected, message) {
|
||||
is( escapeHTML(toHTML(value)), escapeHTML(expected), message );
|
||||
};
|
||||
|
||||
var d = document.createElement('span');
|
||||
updateNodeAttributes(d, {"foo": "bar", "baz": "wibble"});
|
||||
isDOM( d, '<span baz="wibble" foo="bar"/>', "updateNodeAttributes" );
|
||||
|
||||
var d = document.createElement('span');
|
||||
appendChildNodes(d, 'word up', [document.createElement('span')]);
|
||||
isDOM( d, '<span>word up<span/></span>', 'appendChildNodes' );
|
||||
|
||||
replaceChildNodes(d, 'Think Different');
|
||||
isDOM( d, '<span>Think Different</span>', 'replaceChildNodes' );
|
||||
|
||||
|
||||
insertSiblingNodesBefore(d.childNodes[0], 'word up', document.createElement('span'));
|
||||
isDOM( d, '<span>word up<span/>Think Different</span>', 'insertSiblingNodesBefore' );
|
||||
|
||||
insertSiblingNodesAfter(d.childNodes[0], 'purple monkey', document.createElement('span'));
|
||||
isDOM( d, '<span>word uppurple monkey<span/><span/>Think Different</span>', 'insertSiblingNodesAfter' );
|
||||
|
||||
d = createDOM("span");
|
||||
isDOM( d, "<span/>", "createDOM empty" );
|
||||
|
||||
|
||||
d = createDOM("span", {"foo": "bar", "baz": "wibble"});
|
||||
isDOM( d, '<span baz="wibble" foo="bar"/>', "createDOM attributes" );
|
||||
|
||||
d = createDOM("span", {"foo": "bar", "baz": "wibble", "spam": "egg"}, "one", "two", "three");
|
||||
is( getNodeAttribute(d, 'foo'), "bar", "createDOM attribute" );
|
||||
is( getNodeAttribute(d, 'baz'), "wibble", "createDOM attribute" );
|
||||
removeNodeAttribute(d, "spam");
|
||||
is( scrapeText(d), "onetwothree", "createDOM contents" );
|
||||
|
||||
isDOM( d, '<span baz="wibble" foo="bar">onetwothree</span>', "createDOM contents" );
|
||||
|
||||
d = createDOM("span", null, function (f) {
|
||||
return this.nodeName.toLowerCase() + "hi" + f.nodeName.toLowerCase();});
|
||||
isDOM( d, '<span>spanhispan</span>', 'createDOM function call' );
|
||||
|
||||
d = createDOM("span", null, {msg: "hi", dom: function (f) {
|
||||
return f.nodeName.toLowerCase() + this.msg; }});
|
||||
isDOM( d, '<span>spanhi</span>', 'createDOM this.dom() call' );
|
||||
|
||||
d = createDOM("span", null, {msg: "hi", __dom__: function (f) {
|
||||
return f.nodeName.toLowerCase() + this.msg; }});
|
||||
isDOM( d, '<span>spanhi</span>', 'createDOM this.__dom__() call' );
|
||||
|
||||
d = createDOM("span", null, range(4));
|
||||
isDOM( d, '<span>0123</span>', 'createDOM iterable' );
|
||||
|
||||
|
||||
var d = {"taco": "pork"};
|
||||
registerDOMConverter("taco",
|
||||
function (o) { return !isUndefinedOrNull(o.taco); },
|
||||
function (o) { return "Goddamn, I like " + o.taco + " tacos"; }
|
||||
);
|
||||
d = createDOM("span", null, d);
|
||||
// not yet public API
|
||||
domConverters.unregister("taco");
|
||||
|
||||
isDOM( d, "<span>Goddamn, I like pork tacos</span>", "createDOM with custom converter" );
|
||||
|
||||
is(
|
||||
escapeHTML(toHTML(SPAN(null))),
|
||||
escapeHTML(toHTML(createDOM("span", null))),
|
||||
"createDOMFunc vs createDOM"
|
||||
);
|
||||
|
||||
is( scrapeText(d), "Goddamn, I like pork tacos", "scrape OK" );
|
||||
is( scrapeText(d, true).join(""), "Goddamn, I like pork tacos", "scrape Array OK" );
|
||||
|
||||
var st = DIV(null, STRONG(null, "d"), "oor ", STRONG(null, "f", SPAN(null, "r"), "a"), "me");
|
||||
is( scrapeText(st), "door frame", "scrape in-order" );
|
||||
|
||||
|
||||
ok( !isUndefinedOrNull(getElement("test")), "getElement might work" );
|
||||
ok( !isUndefinedOrNull($("test")), "$alias$$ CASH MONEY alias might work" );
|
||||
|
||||
d = createDOM("span", null, "one", "two");
|
||||
swapDOM(d.childNodes[0], document.createTextNode("uno"));
|
||||
isDOM( d, "<span>unotwo</span>", "swapDOM" );
|
||||
|
||||
is( scrapeText(d, true).join(" "), "uno two", "multi-node scrapeText" );
|
||||
/*
|
||||
|
||||
TODO:
|
||||
addLoadEvent (async test?)
|
||||
|
||||
*/
|
||||
|
||||
d = createDOM("span", {"class": "foo"});
|
||||
setElementClass(d, "bar baz");
|
||||
ok( d.className == "bar baz", "setElementClass");
|
||||
toggleElementClass("bar", d);
|
||||
ok( d.className == "baz", "toggleElementClass: " + d.className);
|
||||
toggleElementClass("bar", d);
|
||||
ok( hasElementClass(d, "baz", "bar"),
|
||||
"toggleElementClass 2: " + d.className);
|
||||
addElementClass(d, "bar");
|
||||
ok( hasElementClass(d, "baz", "bar"),
|
||||
"toggleElementClass 3: " + d.className);
|
||||
ok( addElementClass(d, "blah"), "addElementClass return");
|
||||
ok( hasElementClass(d, "baz", "bar", "blah"), "addElementClass action");
|
||||
ok( !hasElementClass(d, "not"), "hasElementClass single");
|
||||
ok( !hasElementClass(d, "baz", "not"), "hasElementClass multiple");
|
||||
ok( removeElementClass(d, "blah"), "removeElementClass" );
|
||||
ok( !removeElementClass(d, "blah"), "removeElementClass again" );
|
||||
ok( !hasElementClass(d, "blah"), "removeElementClass again (hasElement)" );
|
||||
removeElementClass(d, "baz");
|
||||
ok( !swapElementClass(d, "blah", "baz"), "false swapElementClass" );
|
||||
ok( !hasElementClass(d, "baz"), "false swapElementClass from" );
|
||||
ok( !hasElementClass(d, "blah"), "false swapElementClass to" );
|
||||
addElementClass(d, "blah");
|
||||
ok( swapElementClass(d, "blah", "baz"), "swapElementClass" );
|
||||
ok( hasElementClass(d, "baz"), "swapElementClass has toClass" );
|
||||
ok( !hasElementClass(d, "blah"), "swapElementClass !has fromClass" );
|
||||
ok( !swapElementClass(d, "blah", "baz"), "swapElementClass twice" );
|
||||
ok( hasElementClass(d, "baz"), "swapElementClass has toClass" );
|
||||
ok( !hasElementClass(d, "blah"), "swapElementClass !has fromClass" );
|
||||
|
||||
TABLE;
|
||||
TBODY;
|
||||
TR;
|
||||
var t = TABLE(null,
|
||||
TBODY({"class": "foo bar", "id":"tbody0"},
|
||||
TR({"class": "foo", "id":"tr0"}),
|
||||
TR({"class": "bar", "id":"tr1"})
|
||||
)
|
||||
);
|
||||
|
||||
var matchElements = getElementsByTagAndClassName;
|
||||
is(
|
||||
map(itemgetter("id"), matchElements(null, "foo", t)).join(" "),
|
||||
"tbody0 tr0",
|
||||
"getElementsByTagAndClassName found all tags with foo class"
|
||||
);
|
||||
is(
|
||||
map(itemgetter("id"), matchElements("tr", "foo", t)).join(" "),
|
||||
"tr0",
|
||||
"getElementsByTagAndClassName found all tr tags with foo class"
|
||||
);
|
||||
is(
|
||||
map(itemgetter("id"), matchElements("tr", null, t)).join(" "),
|
||||
"tr0 tr1",
|
||||
"getElementsByTagAndClassName found all tr tags"
|
||||
);
|
||||
|
||||
var oldDoc = document;
|
||||
var doc = MochiKit.MockDOM.createDocument();
|
||||
is( currentDocument(), document, "currentDocument() correct" );
|
||||
withDocument(doc, function () {
|
||||
ok( document != doc, "global doc unchanged" );
|
||||
is( currentDocument(), doc, "currentDocument() correct" );
|
||||
var h1 = H1();
|
||||
var span = SPAN(null, "foo", h1);
|
||||
appendChildNodes(currentDocument().body, span);
|
||||
});
|
||||
is( document, oldDoc, "doc restored" );
|
||||
is( doc.childNodes.length, 1, "doc has one child" );
|
||||
is( doc.body.childNodes.length, 1, "body has one child" );
|
||||
var sp = doc.body.childNodes[0];
|
||||
is( sp.nodeName, "SPAN", "only child is SPAN" );
|
||||
is( sp.childNodes.length, 2, "SPAN has two childNodes" );
|
||||
is( sp.childNodes[0].nodeValue, "foo", "first node is text" );
|
||||
is( sp.childNodes[1].nodeName, "H1", "second child is H1" );
|
||||
|
||||
is( currentDocument(), document, "currentDocument() correct" );
|
||||
try {
|
||||
withDocument(doc, function () {
|
||||
ok( document != doc, "global doc unchanged" );
|
||||
is( currentDocument(), doc, "currentDocument() correct" );
|
||||
throw new Error("foo");
|
||||
});
|
||||
ok( false, "didn't throw" );
|
||||
} catch (e) {
|
||||
ok( true, "threw" );
|
||||
}
|
||||
|
||||
var mockWindow = {"foo": "bar"};
|
||||
is (currentWindow(), window, "currentWindow ok");
|
||||
withWindow(mockWindow, function () {
|
||||
is(currentWindow(), mockWindow, "withWindow ok");
|
||||
});
|
||||
is (currentWindow(), window, "currentWindow ok");
|
||||
|
||||
doc = MochiKit.MockDOM.createDocument();
|
||||
var frm;
|
||||
withDocument(doc, function () {
|
||||
frm = FORM({name: "ignore"},
|
||||
INPUT({name:"foo", value:"bar"}),
|
||||
INPUT({name:"foo", value:"bar"}),
|
||||
INPUT({name:"baz", value:"bar"})
|
||||
);
|
||||
});
|
||||
var kv = formContents(frm);
|
||||
is( kv[0].join(","), "foo,foo,baz", "mock formContents names" );
|
||||
is( kv[1].join(","), "bar,bar,bar", "mock formContents values" );
|
||||
is( queryString(frm), "foo=bar&foo=bar&baz=bar", "mock queryString hook" );
|
||||
|
||||
var kv = formContents("form_test");
|
||||
is( kv[0].join(","), "select,selmultiple,selmultiple,hidden,radio_on", "formContents names" );
|
||||
is( kv[1].join(","), "foo,bar,baz,test,2", "formContents values" );
|
||||
is( queryString("form_test"), "select=foo&selmultiple=bar&selmultiple=baz&hidden=test&radio_on=2", "queryString hook" );
|
||||
kv = formContents("form_test2");
|
||||
is( kv[0].join(","), "selempty,selempty2", "formContents names empty option values" );
|
||||
is( kv[1].join(","), ",foo", "formContents empty option values" );
|
||||
is( queryString("form_test2"), "selempty=&selempty2=foo", "queryString empty option values" );
|
||||
|
||||
var d = DIV(null, SPAN(), " \n\t", SPAN(), "foo", SPAN(), " ");
|
||||
is( d.childNodes.length, 6, "removeEmptyNodes test conditions correct" );
|
||||
removeEmptyTextNodes(d);
|
||||
is( d.childNodes.length, 4, "removeEmptyNodes" );
|
||||
|
||||
is( getFirstParentByTagAndClassName('child', 'div', 'two'), getElement("parentTwo"), "getFirstParentByTagAndClassName found parent" );
|
||||
is( getFirstParentByTagAndClassName('child', 'div'), getElement("parentZero"), "getFirstParentByTagAndClassName found parent (any class)" );
|
||||
is( getFirstParentByTagAndClassName('child', '*', 'two'), getElement("parentTwo"), "getFirstParentByTagAndClassName found parent (any tag)" );
|
||||
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,39 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DateTime.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_DateTime.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
tests.test_DateTime({ok:ok, is:is});
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,54 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Color.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Signal.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Visual.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DragAndDrop.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
<style type="text/css">
|
||||
.drop-hover {
|
||||
}
|
||||
#drag1 {
|
||||
visibility: hidden;
|
||||
}
|
||||
#drop1 {
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='drag1'>drag1</div>
|
||||
<div id='drop1'>drop1</div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_DragAndDrop.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
// Counting the number of tests is really lame
|
||||
tests.test_DragAndDrop({ok:ok, is:is});
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,39 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Format.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_Format.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
tests.test_Format({ok:ok, is:is});
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,38 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_Iter.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
tests.test_Iter({ok:ok, is:is});
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="JSAN.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
// TODO: Make this a harness for the other tests
|
||||
JSAN.use('Test.More');
|
||||
JSAN.addRepository('..');
|
||||
var lst = [];
|
||||
plan({"tests": 1});
|
||||
var wc = {};
|
||||
wc['MochiKit'] = true;
|
||||
for (var k in window) { wc[k] = true; }
|
||||
for (var k in window) { wc[k] = true; }
|
||||
JSAN.use('MochiKit.MochiKit', []);
|
||||
for (var k in window) {
|
||||
if (!(k in wc) && !(k.charAt(0) == '[')) {
|
||||
lst.push(k);
|
||||
}
|
||||
}
|
||||
lst.sort();
|
||||
pollution = lst.join(" ");
|
||||
is(pollution, "compare reduce", "namespace pollution?");
|
||||
JSAN.use('MochiKit.MochiKit');
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Logging.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_Logging.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
tests.test_Logging({ok:ok, is:is});
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
is( isUndefined(null), false, "null is not undefined" );
|
||||
is( isUndefined(""), false, "empty string is not undefined" );
|
||||
is( isUndefined(undefined), true, "undefined is undefined" );
|
||||
is( isUndefined({}.foo), true, "missing property is undefined" );
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,274 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/MockDOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Selector.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
<style type="text/css">
|
||||
p, #sequence {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>Test originally from <a href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a>.</p>
|
||||
|
||||
<p>Here are some links in a normal paragraph: <a href="http://www.google.com/" title="Google!">Google</a>, <a href="http://groups.google.com/">Google Groups</a>. This link has <code>class="blog"</code>: <a href="http://diveintomark.org/" class="blog" fakeattribute="bla">diveintomark</a></p>
|
||||
<div id="foo">
|
||||
<p>Everything inside the red border is inside a div with <code>id="foo"</code>.</p>
|
||||
<p>This is a normal link: <a href="http://www.yahoo.com/">Yahoo</a></p>
|
||||
|
||||
<a style="display: none" href="http://www.example.com/outsidep">This a is not inside a p</a>
|
||||
|
||||
<p>This link has <code>class="blog"</code>: <a href="http://simon.incutio.com/" class="blog">Simon Willison's Weblog</a></p>
|
||||
<p>This <span><a href="http://www.example.com/insidespan">link</a></span> is inside a span, not directly child of p</p>
|
||||
<p lang="en-us">Nonninn</p>
|
||||
<p lang="is-IS">Sniðugt</p>
|
||||
<p>
|
||||
<input type="button" name="enabled" value="enabled" id="enabled">
|
||||
<input type="button" name="disabled" value="disabled" id="disabled" disabled="1" />
|
||||
<input type="checkbox" name="checked" value="checked" id="checked" checked="1" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="sequence">
|
||||
<a href="http://www.example.com/link1">Link 1</a>
|
||||
<a href="http://www.example.com/link2">Link 2</a>
|
||||
<a href="http://www.example.com/link3">Link 3</a>
|
||||
<a href="http://www.example.com/link4">Link 4</a>
|
||||
<p>Something else</p>
|
||||
<a href="http://www.example.com/link5">Link 5</a>
|
||||
<a href="http://www.example.com/link6">Link 6</a>
|
||||
<a href="http://www.example.com/link7">Link 7</a>
|
||||
<a href="http://www.example.com/link8">Link 8</a>
|
||||
</div>
|
||||
|
||||
<div id="multiclass" class="multiple classnames here"></div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
var testExpected = function (res, exp, lbl) {
|
||||
for (var i=0; i < res.length; i ++) {
|
||||
is( res[i].href, exp[i], lbl + ' (' + i + ')');
|
||||
}
|
||||
};
|
||||
|
||||
var expected = ['http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector',
|
||||
'http://www.google.com/',
|
||||
'http://groups.google.com/',
|
||||
'http://diveintomark.org/',
|
||||
'http://www.yahoo.com/',
|
||||
'http://www.example.com/outsidep',
|
||||
'http://simon.incutio.com/',
|
||||
'http://www.example.com/insidespan',
|
||||
'http://www.example.com/link1',
|
||||
'http://www.example.com/link2',
|
||||
'http://www.example.com/link3',
|
||||
'http://www.example.com/link4',
|
||||
'http://www.example.com/link5',
|
||||
'http://www.example.com/link6',
|
||||
'http://www.example.com/link7',
|
||||
'http://www.example.com/link8'];
|
||||
var results = $$('a');
|
||||
testExpected(results, expected, "'a' selector");
|
||||
|
||||
expected = ['http://diveintomark.org/', 'http://simon.incutio.com/'];
|
||||
results = $$('p a.blog');
|
||||
testExpected(results, expected, "'p a.blog' selector");
|
||||
|
||||
expected = ['http://www.yahoo.com/',
|
||||
'http://www.example.com/outsidep',
|
||||
'http://simon.incutio.com/',
|
||||
'http://www.example.com/insidespan',
|
||||
'http://www.example.com/link1',
|
||||
'http://www.example.com/link2',
|
||||
'http://www.example.com/link3',
|
||||
'http://www.example.com/link4',
|
||||
'http://www.example.com/link5',
|
||||
'http://www.example.com/link6',
|
||||
'http://www.example.com/link7',
|
||||
'http://www.example.com/link8'];
|
||||
results = $$('div a');
|
||||
testExpected(results, expected, "'div a' selector");
|
||||
|
||||
expected = ['http://www.yahoo.com/',
|
||||
'http://www.example.com/outsidep',
|
||||
'http://simon.incutio.com/',
|
||||
'http://www.example.com/insidespan'];
|
||||
results = $$('div#foo a');
|
||||
testExpected(results, expected, "'div#foo a' selector");
|
||||
|
||||
expected = ['http://simon.incutio.com/',
|
||||
'http://www.example.com/insidespan'];
|
||||
results = $$('#foo a.blog');
|
||||
testExpected(results, expected, "'#foo a.blog' selector");
|
||||
|
||||
expected = ['http://diveintomark.org/',
|
||||
'http://simon.incutio.com/',
|
||||
'http://www.example.com/insidespan'];
|
||||
results = $$('.blog');
|
||||
testExpected(results, expected, "'.blog' selector");
|
||||
|
||||
expected = ['http://www.google.com/',
|
||||
'http://www.yahoo.com/',
|
||||
'http://www.example.com/outsidep',
|
||||
'http://www.example.com/insidespan',
|
||||
'http://www.example.com/link1',
|
||||
'http://www.example.com/link2',
|
||||
'http://www.example.com/link3',
|
||||
'http://www.example.com/link4',
|
||||
'http://www.example.com/link5',
|
||||
'http://www.example.com/link6',
|
||||
'http://www.example.com/link7',
|
||||
'http://www.example.com/link8'];
|
||||
results = $$('a[href^="http://www"]');
|
||||
testExpected(results, expected, "'a[href^=http://www]' selector");
|
||||
|
||||
expected = ['http://diveintomark.org/'];
|
||||
results = $$('a[href$="org/"]');
|
||||
testExpected(results, expected, "'a[href$=org/]' selector");
|
||||
|
||||
expected = ['http://www.google.com/',
|
||||
'http://groups.google.com/'];
|
||||
results = $$('a[href*="google"]');
|
||||
testExpected(results, expected, "'a[href*=google]' selector");
|
||||
|
||||
expected = ['http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector'];
|
||||
results = $$('a[rel="bookmark"]');
|
||||
testExpected(results, expected, "'a[rel=bookmark]' selector");
|
||||
|
||||
expected = ['http://diveintomark.org/'];
|
||||
results = $$('a[fakeattribute]');
|
||||
testExpected(results, expected, "'a[fakeattribute]' selector");
|
||||
|
||||
/* This doesn't work in IE due to silly DOM implementation
|
||||
expected = ['http://www.google.com/'];
|
||||
results = $$('a[title]');
|
||||
testExpected(results, expected, "'a[title]' selector");
|
||||
*/
|
||||
|
||||
results = $$('p[lang|="en"]');
|
||||
is( results[0].firstChild.nodeValue, 'Nonninn', "'p[lang|=en]' selector");
|
||||
|
||||
expected = ['http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector',
|
||||
'http://www.google.com/',
|
||||
'http://groups.google.com/',
|
||||
'http://diveintomark.org/',
|
||||
'http://www.yahoo.com/',
|
||||
'http://simon.incutio.com/',
|
||||
'http://www.example.com/insidespan'];
|
||||
results = $$('p > a');
|
||||
testExpected(results, expected, "'p > a' selector");
|
||||
|
||||
expected = ['http://www.example.com/insidespan'];
|
||||
results = $$('span > a');
|
||||
testExpected(results, expected, "'span > a' selector");
|
||||
|
||||
expected = ['http://groups.google.com/',
|
||||
'http://www.example.com/link2',
|
||||
'http://www.example.com/link3',
|
||||
'http://www.example.com/link4',
|
||||
'http://www.example.com/link6',
|
||||
'http://www.example.com/link7',
|
||||
'http://www.example.com/link8'];
|
||||
results = $$('a + a');
|
||||
testExpected(results, expected, "'a + a' selector");
|
||||
|
||||
expected = ['http://www.example.com/link1',
|
||||
'http://www.example.com/link3',
|
||||
'http://www.example.com/link6',
|
||||
'http://www.example.com/link8'];
|
||||
results = $$('#sequence a:nth-child(odd)');
|
||||
testExpected(results, expected, "'#sequence a:nth-child(odd)' selector");
|
||||
|
||||
expected = ['http://www.example.com/link1',
|
||||
'http://www.example.com/link3',
|
||||
'http://www.example.com/link5',
|
||||
'http://www.example.com/link7'];
|
||||
results = $$('#sequence a:nth-of-type(odd)');
|
||||
testExpected(results, expected, "'#sequence a:nth-of-type(odd)' selector");
|
||||
|
||||
expected = ['http://www.example.com/link1',
|
||||
'http://www.example.com/link4',
|
||||
'http://www.example.com/link7'];
|
||||
results = $$('#sequence a:nth-of-type(3n+1)');
|
||||
testExpected(results, expected, "'#sequence a:nth-of-type(3n+1)' selector");
|
||||
|
||||
expected = ['http://www.example.com/link5'];
|
||||
results = $$('#sequence a:nth-child(6)');
|
||||
testExpected(results, expected, "'#sequence a:nth-child(6)' selector");
|
||||
|
||||
expected = ['http://www.example.com/link5'];
|
||||
results = $$('#sequence a:nth-of-type(5)');
|
||||
testExpected(results, expected, "'#sequence a:nth-of-type(5)' selector");
|
||||
|
||||
expected = [$('enabled'), $('checked')];
|
||||
results = $$('body :enabled');
|
||||
for (var i=0; i < results.length; i ++) {
|
||||
is( results[i], expected[i], "'body :enabled" + ' (' + i + ')');
|
||||
}
|
||||
|
||||
expected = [$('disabled')];
|
||||
results = $$('body :disabled');
|
||||
for (var i=0; i < results.length; i ++) {
|
||||
is( results[i], expected[i], "'body :disabled" + ' (' + i + ')');
|
||||
}
|
||||
|
||||
expected = [$('checked')];
|
||||
results = $$('body :checked');
|
||||
for (var i=0; i < results.length; i ++) {
|
||||
is( results[i], expected[i], "'body :checked" + ' (' + i + ')');
|
||||
}
|
||||
|
||||
expected = document.getElementsByTagName('p');
|
||||
results = $$('a[href$=outsidep] ~ *');
|
||||
for (var i=0; i < results.length; i ++) {
|
||||
is( results[i], expected[i+4], "'a[href$=outsidep] ~ *' selector" + ' (' + i + ')');
|
||||
}
|
||||
|
||||
expected = [document.documentElement];
|
||||
results = $$(':root');
|
||||
for (var i=0; i < results.length; i ++) {
|
||||
is( results[i], expected[i], "':root' selector" + ' (' + i + ')');
|
||||
}
|
||||
|
||||
expected = [$('multiclass')];
|
||||
results = $$('[class~=classnames]');
|
||||
for (var i=0; i < results.length; i ++) {
|
||||
is( results[i], expected[i], "'~=' attribute test" + ' (' + i + ')');
|
||||
}
|
||||
|
||||
var doc = MochiKit.MockDOM.createDocument();
|
||||
appendChildNodes(doc.body, A({"href": "http://www.example.com/insideAnotherDocument"}, "Inside a document"));
|
||||
withDocument(doc, function(){
|
||||
is( $$(":root")[0], doc, ":root on a different document" );
|
||||
is( $$("a")[0], doc.body.firstChild, "a inside a different document" );
|
||||
});
|
||||
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Signal.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Logging.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Please ignore this button: <input type="submit" id="submit" /><br />
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript" src="test_Signal.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
|
||||
tests.test_Signal({ok:ok, is:is});
|
||||
ok(true, "test suite finished!");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok(false, s);
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,141 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/MockDOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Color.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Logging.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
</head>
|
||||
<body style="border: 0; margin: 0; padding: 0;">
|
||||
|
||||
<div id="styleTest" style="position: absolute; left: 400px; top: 100px; width: 100px; height: 100px; background: rgb(255, 0, 0); opacity: 0.5; filter: alpha(opacity=50); font-size: 10px">TEST<span id="styleSubTest">SUB</span></div>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
|
||||
try {
|
||||
|
||||
// initial
|
||||
var pos = getElementPosition('styleTest');
|
||||
is(pos.x, 400, 'initial x position');
|
||||
is(pos.y, 100, 'initial y position');
|
||||
|
||||
// moved
|
||||
var newPos = new MochiKit.Style.Coordinates(500, 200);
|
||||
setElementPosition('styleTest', newPos);
|
||||
pos = getElementPosition('styleTest');
|
||||
is(pos.x, 500, 'updated x position');
|
||||
is(pos.y, 200, 'updated y position');
|
||||
|
||||
// moved with relativeTo
|
||||
anotherPos = new MochiKit.Style.Coordinates(100, 100);
|
||||
pos = getElementPosition('styleTest', anotherPos);
|
||||
is(pos.x, 400, 'updated x position (using relativeTo parameter)');
|
||||
is(pos.y, 100, 'updated y position (using relativeTo parameter)');
|
||||
|
||||
// Coordinates object
|
||||
pos = getElementPosition({x: 123, y: 321});
|
||||
is(pos.x, 123, 'passthrough x position');
|
||||
is(pos.y, 321, 'passthrough y position');
|
||||
|
||||
// Coordinates object with relativeTo
|
||||
pos = getElementPosition({x: 123, y: 321}, {x: 100, y: 50});
|
||||
is(pos.x, 23, 'passthrough x position (using relativeTo parameter)');
|
||||
is(pos.y, 271, 'passthrough y position (using relativeTo parameter)');
|
||||
|
||||
pos = getElementPosition('garbage');
|
||||
is(typeof(pos), 'undefined',
|
||||
'invalid element should return an undefined position');
|
||||
|
||||
// Only set one coordinate
|
||||
setElementPosition('styleTest', {'x': 300});
|
||||
pos = getElementPosition('styleTest');
|
||||
is(pos.x, 300, 'updated only x position');
|
||||
is(pos.y, 200, 'not updated y position');
|
||||
|
||||
var mc = MochiKit.Color.Color;
|
||||
var red = mc.fromString('rgb(255,0,0)');
|
||||
var color = null;
|
||||
|
||||
color = mc.fromString(getStyle('styleTest', 'background-color'));
|
||||
is(color.toHexString(), red.toHexString(),
|
||||
'test getStyle selector case');
|
||||
|
||||
color = mc.fromString(getStyle('styleTest', 'backgroundColor'));
|
||||
is(color.toHexString(), red.toHexString(),
|
||||
'test getStyle camel case');
|
||||
|
||||
is(getStyle('styleSubTest', 'font-size'), '10px',
|
||||
'test computed getStyle selector case');
|
||||
|
||||
is(getStyle('styleSubTest', 'fontSize'), '10px',
|
||||
'test computed getStyle camel case');
|
||||
|
||||
is(eval(getStyle('styleTest', 'opacity')), 0.5,
|
||||
'test getStyle opacity');
|
||||
|
||||
is(getStyle('styleTest', 'opacity'), 0.5, 'test getOpacity');
|
||||
|
||||
setStyle('styleTest', {'opacity': 0.2});
|
||||
is(getStyle('styleTest', 'opacity'), 0.2, 'test setOpacity');
|
||||
|
||||
setStyle('styleTest', {'opacity': 0});
|
||||
is(getStyle('styleTest', 'opacity'), 0, 'test setOpacity');
|
||||
|
||||
setStyle('styleTest', {'opacity': 1});
|
||||
var t = getStyle('styleTest', 'opacity');
|
||||
ok(t > 0.999 && t <= 1, 'test setOpacity');
|
||||
|
||||
var dims = getElementDimensions('styleTest');
|
||||
is(dims.w, 100, 'getElementDimensions w ok');
|
||||
is(dims.h, 100, 'getElementDimensions h ok');
|
||||
|
||||
setElementDimensions('styleTest', {'w': 200, 'h': 150});
|
||||
dims = getElementDimensions('styleTest');
|
||||
is(dims.w, 200, 'setElementDimensions w ok');
|
||||
is(dims.h, 150, 'setElementDimensions h ok');
|
||||
|
||||
setElementDimensions('styleTest', {'w': 150});
|
||||
dims = getElementDimensions('styleTest');
|
||||
is(dims.w, 150, 'setElementDimensions only w ok');
|
||||
is(dims.h, 150, 'setElementDimensions h not updated ok');
|
||||
|
||||
hideElement('styleTest');
|
||||
dims = getElementDimensions('styleTest');
|
||||
is(dims.w, 150, 'getElementDimensions w ok when display none');
|
||||
is(dims.h, 150, 'getElementDimensions h ok when display none');
|
||||
|
||||
dims = getViewportDimensions();
|
||||
is(dims.w > 0, true, 'test getViewportDimensions w');
|
||||
is(dims.h > 0, true, 'test getViewportDimensions h');
|
||||
|
||||
pos = getViewportPosition();
|
||||
is(pos.x, 0, 'test getViewportPosition x');
|
||||
is(pos.y, 0, 'test getViewportPosition y');
|
||||
|
||||
ok( true, "test suite finished!");
|
||||
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,190 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/Base.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Iter.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/DOM.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Async.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Style.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Color.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Signal.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Position.js"></script>
|
||||
<script type="text/javascript" src="../MochiKit/Visual.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
|
||||
<style type="text/css">
|
||||
#elt1, #elt2, #ctn1 {
|
||||
visibility: hidden;
|
||||
font-size: 1em;
|
||||
margin: 2px;
|
||||
}
|
||||
#elt3 {
|
||||
display: none;
|
||||
}
|
||||
#ctn1 {
|
||||
height: 2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id='elt1'>elt1</div>
|
||||
<div id='ctn1'><div id='elt2'></div></div>
|
||||
<div id='elt3'>elt3</div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var TestQueue = function () {
|
||||
};
|
||||
|
||||
TestQueue.prototype = new MochiKit.Visual.ScopedQueue();
|
||||
|
||||
MochiKit.Base.update(TestQueue.prototype, {
|
||||
startLoop: function (func, interval) {
|
||||
this.started = true;
|
||||
var timePos = new Date().getTime();
|
||||
while (this.started) {
|
||||
timePos += interval;
|
||||
MochiKit.Base.map(function (effect) {
|
||||
effect.loop(timePos);
|
||||
}, this.effects);
|
||||
}
|
||||
},
|
||||
stopLoop: function () {
|
||||
this.started = false;
|
||||
}
|
||||
});
|
||||
|
||||
var gl = new TestQueue();
|
||||
MochiKit.Visual.Queues.instances['global'] = gl;
|
||||
MochiKit.Visual.Queues.instances['elt1'] = gl;
|
||||
MochiKit.Visual.Queues.instances['elt2'] = gl;
|
||||
MochiKit.Visual.Queues.instances['elt3'] = gl;
|
||||
MochiKit.Visual.Queues.instances['ctn1'] = gl;
|
||||
MochiKit.Visual.Queue = gl;
|
||||
|
||||
pulsate("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display != 'none', true, "pulsate ok");
|
||||
}});
|
||||
|
||||
pulsate("elt1", {pulses: 2, afterFinish: function () {
|
||||
is(getElement('elt1').style.display != 'none', true, "pulsate with numbered pulses ok");
|
||||
}});
|
||||
|
||||
shake("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display != 'none', true, "shake ok");
|
||||
}});
|
||||
|
||||
fade("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "fade ok");
|
||||
}});
|
||||
|
||||
appear("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display != 'none', true, "appear ok");
|
||||
}});
|
||||
|
||||
toggle("elt1", "size", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "toggle size ok");
|
||||
}});
|
||||
|
||||
toggle("elt1", "size", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display != 'none', true, "toggle size reverse ok");
|
||||
}});
|
||||
|
||||
Morph("elt1", {"style": {"font-size": "2em"}, afterFinish: function () {
|
||||
is(getStyle("elt1", "font-size"), "2em", "Morph OK");
|
||||
}});
|
||||
|
||||
Morph("elt1", {"style": {"font-size": "1em", "margin-left": "4px"}, afterFinish: function () {
|
||||
is(getStyle("elt1", "font-size"), "1em", "Morph multiple (font) OK");
|
||||
is(getStyle("elt1", "margin-left"), "4px", "Morph multiple (margin) OK");
|
||||
}});
|
||||
|
||||
switchOff("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "switchOff ok");
|
||||
}});
|
||||
|
||||
grow("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display != 'none', true, "grow ok");
|
||||
}});
|
||||
|
||||
shrink("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "shrink ok");
|
||||
}});
|
||||
|
||||
showElement('elt1');
|
||||
dropOut("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "dropOut ok");
|
||||
}});
|
||||
|
||||
showElement('elt1');
|
||||
puff("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "puff ok");
|
||||
}});
|
||||
|
||||
showElement('elt1');
|
||||
fold("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "fold ok");
|
||||
}});
|
||||
|
||||
showElement('elt1');
|
||||
squish("elt1", {afterFinish: function () {
|
||||
is(getElement('elt1').style.display, 'none', "squish ok");
|
||||
}});
|
||||
|
||||
slideUp("ctn1", {afterFinish: function () {
|
||||
is(getElement('ctn1').style.display, 'none', "slideUp ok");
|
||||
}});
|
||||
|
||||
slideDown("ctn1", {afterFinish: function () {
|
||||
is(getElement('ctn1').style.display != 'none', true, "slideDown ok");
|
||||
}});
|
||||
|
||||
blindDown("ctn1", {afterFinish: function () {
|
||||
is(getElement('ctn1').style.display != 'none', true, "blindDown ok");
|
||||
}});
|
||||
|
||||
blindUp("ctn1", {afterFinish: function () {
|
||||
is(getElement('ctn1').style.display, 'none', "blindUp ok");
|
||||
}});
|
||||
|
||||
multiple(["elt1", "ctn1"], appear, {afterFinish: function (effect) {
|
||||
is(effect.element.style.display != 'none', true, "multiple ok");
|
||||
}});
|
||||
|
||||
toggle("elt3", "size", {afterFinish: function () {
|
||||
is(getElement('elt3').style.display != 'none', true, "toggle with css ok");
|
||||
}});
|
||||
|
||||
toggle("elt3", "size", {afterFinish: function () {
|
||||
is(getElement('elt3').style.display, 'none', "toggle with css ok");
|
||||
}});
|
||||
|
||||
var toTests = [roundElement, roundClass, tagifyText, Opacity, Move, Scale, Highlight, ScrollTo, Morph];
|
||||
for (var m in toTests) {
|
||||
toTests[m]("elt1");
|
||||
ok(true, toTests[m].NAME + " doesn't need 'new' keyword");
|
||||
}
|
||||
ok(true, "visual suite finished");
|
||||
|
||||
} catch (err) {
|
||||
|
||||
var s = "test suite failure!\n";
|
||||
var o = {};
|
||||
var k = null;
|
||||
for (k in err) {
|
||||
// ensure unique keys?!
|
||||
if (!o[k]) {
|
||||
s += k + ": " + err[k] + "\n";
|
||||
o[k] = err[k];
|
||||
}
|
||||
}
|
||||
ok ( false, s );
|
||||
SimpleTest.finish();
|
||||
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/ajax/mochikit/tests/SimpleTest
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = $(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
SimpleTest.js \
|
||||
TestRunner.js \
|
||||
test.css \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
|
@ -0,0 +1,366 @@
|
|||
/**
|
||||
* SimpleTest, a partial Test.Simple/Test.More API compatible test library.
|
||||
*
|
||||
* Why?
|
||||
*
|
||||
* Test.Simple doesn't work on IE < 6.
|
||||
* TODO:
|
||||
* * Support the Test.Simple API used by MochiKit, to be able to test MochiKit
|
||||
* itself against IE 5.5
|
||||
*
|
||||
**/
|
||||
|
||||
if (typeof(SimpleTest) == "undefined") {
|
||||
var SimpleTest = {};
|
||||
}
|
||||
|
||||
// Check to see if the TestRunner is present and has logging
|
||||
if (typeof(parent) != "undefined" && parent.TestRunner) {
|
||||
SimpleTest._logEnabled = parent.TestRunner.logEnabled;
|
||||
}
|
||||
|
||||
SimpleTest._tests = [];
|
||||
SimpleTest._stopOnLoad = true;
|
||||
|
||||
/**
|
||||
* Something like assert.
|
||||
**/
|
||||
SimpleTest.ok = function (condition, name, diag) {
|
||||
var test = {'result': !!condition, 'name': name, 'diag': diag || ""};
|
||||
if (SimpleTest._logEnabled) {
|
||||
var msg = test.result ? "PASS" : "FAIL";
|
||||
msg += " | " + test.name;
|
||||
if (test.result) {
|
||||
parent.TestRunner.logger.log(msg);
|
||||
} else {
|
||||
msg += " | " + test.diag;
|
||||
parent.TestRunner.logger.error(msg);
|
||||
}
|
||||
}
|
||||
SimpleTest._tests.push(test);
|
||||
};
|
||||
|
||||
/**
|
||||
* Roughly equivalent to ok(a==b, name)
|
||||
**/
|
||||
SimpleTest.is = function (a, b, name) {
|
||||
var repr = MochiKit.Base.repr;
|
||||
SimpleTest.ok(a == b, name, "got " + repr(a) + ", expected " + repr(b));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Makes a test report, returns it as a DIV element.
|
||||
**/
|
||||
SimpleTest.report = function () {
|
||||
var DIV = MochiKit.DOM.DIV;
|
||||
var passed = 0;
|
||||
var failed = 0;
|
||||
var results = MochiKit.Base.map(
|
||||
function (test) {
|
||||
var cls, msg;
|
||||
if (test.result) {
|
||||
passed++;
|
||||
cls = "test_ok";
|
||||
msg = "ok - " + test.name;
|
||||
} else {
|
||||
failed++;
|
||||
cls = "test_not_ok";
|
||||
msg = "not ok - " + test.name + " " + test.diag;
|
||||
}
|
||||
return DIV({"class": cls}, msg);
|
||||
},
|
||||
SimpleTest._tests
|
||||
);
|
||||
var summary_class = ((failed == 0) ? 'all_pass' : 'some_fail');
|
||||
return DIV({'class': 'tests_report'},
|
||||
DIV({'class': 'tests_summary ' + summary_class},
|
||||
DIV({'class': 'tests_passed'}, "Passed: " + passed),
|
||||
DIV({'class': 'tests_failed'}, "Failed: " + failed)),
|
||||
results
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle element visibility
|
||||
**/
|
||||
SimpleTest.toggle = function(el) {
|
||||
if (MochiKit.Style.getStyle(el, 'display') == 'block') {
|
||||
el.style.display = 'none';
|
||||
} else {
|
||||
el.style.display = 'block';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle visibility for divs with a specific class.
|
||||
**/
|
||||
SimpleTest.toggleByClass = function (cls) {
|
||||
var elems = getElementsByTagAndClassName('div', cls);
|
||||
MochiKit.Base.map(SimpleTest.toggle, elems);
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the report in the browser
|
||||
**/
|
||||
|
||||
SimpleTest.showReport = function() {
|
||||
var togglePassed = A({'href': '#'}, "Toggle passed tests");
|
||||
var toggleFailed = A({'href': '#'}, "Toggle failed tests");
|
||||
togglePassed.onclick = partial(SimpleTest.toggleByClass, 'test_ok');
|
||||
toggleFailed.onclick = partial(SimpleTest.toggleByClass, 'test_not_ok');
|
||||
var body = document.getElementsByTagName("body")[0];
|
||||
var firstChild = body.childNodes[0];
|
||||
var addNode;
|
||||
if (firstChild) {
|
||||
addNode = function (el) {
|
||||
body.insertBefore(el, firstChild);
|
||||
};
|
||||
} else {
|
||||
addNode = function (el) {
|
||||
body.appendChild(el)
|
||||
};
|
||||
}
|
||||
addNode(togglePassed);
|
||||
addNode(SPAN(null, " "));
|
||||
addNode(toggleFailed);
|
||||
addNode(SimpleTest.report());
|
||||
};
|
||||
|
||||
/**
|
||||
* Tells SimpleTest to don't finish the test when the document is loaded,
|
||||
* useful for asynchronous tests.
|
||||
*
|
||||
* When SimpleTest.waitForExplicitFinish is called,
|
||||
* explicit SimpleTest.finish() is required.
|
||||
**/
|
||||
SimpleTest.waitForExplicitFinish = function () {
|
||||
SimpleTest._stopOnLoad = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Talks to the TestRunner if being ran on a iframe and the parent has a
|
||||
* TestRunner object.
|
||||
**/
|
||||
SimpleTest.talkToRunner = function () {
|
||||
if (typeof(parent) != "undefined" && parent.TestRunner) {
|
||||
parent.TestRunner.testFinished(document);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finishes the tests. This is automatically called, except when
|
||||
* SimpleTest.waitForExplicitFinish() has been invoked.
|
||||
**/
|
||||
SimpleTest.finish = function () {
|
||||
SimpleTest.showReport();
|
||||
SimpleTest.talkToRunner();
|
||||
};
|
||||
|
||||
|
||||
addLoadEvent(function() {
|
||||
if (SimpleTest._stopOnLoad) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
|
||||
// --------------- Test.Builder/Test.More isDeeply() -----------------
|
||||
|
||||
|
||||
SimpleTest.DNE = {dne: 'Does not exist'};
|
||||
SimpleTest.LF = "\r\n";
|
||||
SimpleTest._isRef = function (object) {
|
||||
var type = typeof(object);
|
||||
return type == 'object' || type == 'function';
|
||||
};
|
||||
|
||||
|
||||
SimpleTest._deepCheck = function (e1, e2, stack, seen) {
|
||||
var ok = false;
|
||||
// Either they're both references or both not.
|
||||
var sameRef = !(!SimpleTest._isRef(e1) ^ !SimpleTest._isRef(e2));
|
||||
if (e1 == null && e2 == null) {
|
||||
ok = true;
|
||||
} else if (e1 != null ^ e2 != null) {
|
||||
ok = false;
|
||||
} else if (e1 == SimpleTest.DNE ^ e2 == SimpleTest.DNE) {
|
||||
ok = false;
|
||||
} else if (sameRef && e1 == e2) {
|
||||
// Handles primitives and any variables that reference the same
|
||||
// object, including functions.
|
||||
ok = true;
|
||||
} else if (SimpleTest.isa(e1, 'Array') && SimpleTest.isa(e2, 'Array')) {
|
||||
ok = SimpleTest._eqArray(e1, e2, stack, seen);
|
||||
} else if (typeof e1 == "object" && typeof e2 == "object") {
|
||||
ok = SimpleTest._eqAssoc(e1, e2, stack, seen);
|
||||
} else {
|
||||
// If we get here, they're not the same (function references must
|
||||
// always simply rererence the same function).
|
||||
stack.push({ vals: [e1, e2] });
|
||||
ok = false;
|
||||
}
|
||||
return ok;
|
||||
};
|
||||
|
||||
SimpleTest._eqArray = function (a1, a2, stack, seen) {
|
||||
// Return if they're the same object.
|
||||
if (a1 == a2) return true;
|
||||
|
||||
// JavaScript objects have no unique identifiers, so we have to store
|
||||
// references to them all in an array, and then compare the references
|
||||
// directly. It's slow, but probably won't be much of an issue in
|
||||
// practice. Start by making a local copy of the array to as to avoid
|
||||
// confusing a reference seen more than once (such as [a, a]) for a
|
||||
// circular reference.
|
||||
for (var j = 0; j < seen.length; j++) {
|
||||
if (seen[j][0] == a1) {
|
||||
return seen[j][1] == a2;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, we haven't seen a1 before, so store it with reference
|
||||
// to a2.
|
||||
seen.push([ a1, a2 ]);
|
||||
|
||||
var ok = true;
|
||||
// Only examines enumerable attributes. Only works for numeric arrays!
|
||||
// Associative arrays return 0. So call _eqAssoc() for them, instead.
|
||||
var max = a1.length > a2.length ? a1.length : a2.length;
|
||||
if (max == 0) return SimpleTest._eqAssoc(a1, a2, stack, seen);
|
||||
for (var i = 0; i < max; i++) {
|
||||
var e1 = i > a1.length - 1 ? SimpleTest.DNE : a1[i];
|
||||
var e2 = i > a2.length - 1 ? SimpleTest.DNE : a2[i];
|
||||
stack.push({ type: 'Array', idx: i, vals: [e1, e2] });
|
||||
if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
|
||||
stack.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
};
|
||||
|
||||
SimpleTest._eqAssoc = function (o1, o2, stack, seen) {
|
||||
// Return if they're the same object.
|
||||
if (o1 == o2) return true;
|
||||
|
||||
// JavaScript objects have no unique identifiers, so we have to store
|
||||
// references to them all in an array, and then compare the references
|
||||
// directly. It's slow, but probably won't be much of an issue in
|
||||
// practice. Start by making a local copy of the array to as to avoid
|
||||
// confusing a reference seen more than once (such as [a, a]) for a
|
||||
// circular reference.
|
||||
seen = seen.slice(0);
|
||||
for (var j = 0; j < seen.length; j++) {
|
||||
if (seen[j][0] == o1) {
|
||||
return seen[j][1] == o2;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, we haven't seen o1 before, so store it with reference
|
||||
// to o2.
|
||||
seen.push([ o1, o2 ]);
|
||||
|
||||
// They should be of the same class.
|
||||
|
||||
var ok = true;
|
||||
// Only examines enumerable attributes.
|
||||
var o1Size = 0; for (var i in o1) o1Size++;
|
||||
var o2Size = 0; for (var i in o2) o2Size++;
|
||||
var bigger = o1Size > o2Size ? o1 : o2;
|
||||
for (var i in bigger) {
|
||||
var e1 = o1[i] == undefined ? SimpleTest.DNE : o1[i];
|
||||
var e2 = o2[i] == undefined ? SimpleTest.DNE : o2[i];
|
||||
stack.push({ type: 'Object', idx: i, vals: [e1, e2] });
|
||||
if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
|
||||
stack.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
};
|
||||
|
||||
SimpleTest._formatStack = function (stack) {
|
||||
var variable = '$Foo';
|
||||
for (var i = 0; i < stack.length; i++) {
|
||||
var entry = stack[i];
|
||||
var type = entry['type'];
|
||||
var idx = entry['idx'];
|
||||
if (idx != null) {
|
||||
if (/^\d+$/.test(idx)) {
|
||||
// Numeric array index.
|
||||
variable += '[' + idx + ']';
|
||||
} else {
|
||||
// Associative array index.
|
||||
idx = idx.replace("'", "\\'");
|
||||
variable += "['" + idx + "']";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var vals = stack[stack.length-1]['vals'].slice(0, 2);
|
||||
var vars = [
|
||||
variable.replace('$Foo', 'got'),
|
||||
variable.replace('$Foo', 'expected')
|
||||
];
|
||||
|
||||
var out = "Structures begin differing at:" + SimpleTest.LF;
|
||||
for (var i = 0; i < vals.length; i++) {
|
||||
var val = vals[i];
|
||||
if (val == null) {
|
||||
val = 'undefined';
|
||||
} else {
|
||||
val == SimpleTest.DNE ? "Does not exist" : "'" + val + "'";
|
||||
}
|
||||
}
|
||||
|
||||
out += vars[0] + ' = ' + vals[0] + SimpleTest.LF;
|
||||
out += vars[1] + ' = ' + vals[1] + SimpleTest.LF;
|
||||
|
||||
return ' ' + out;
|
||||
};
|
||||
|
||||
|
||||
SimpleTest.isDeeply = function (it, as, name) {
|
||||
var ok;
|
||||
// ^ is the XOR operator.
|
||||
if (SimpleTest._isRef(it) ^ SimpleTest._isRef(as)) {
|
||||
// One's a reference, one isn't.
|
||||
ok = false;
|
||||
} else if (!SimpleTest._isRef(it) && !SimpleTest._isRef(as)) {
|
||||
// Neither is an object.
|
||||
ok = SimpleTest.is(it, as, name);
|
||||
} else {
|
||||
// We have two objects. Do a deep comparison.
|
||||
var stack = [], seen = [];
|
||||
if ( SimpleTest._deepCheck(it, as, stack, seen)) {
|
||||
ok = SimpleTest.ok(true, name);
|
||||
} else {
|
||||
ok = SimpleTest.ok(false, name, SimpleTest._formatStack(stack));
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
};
|
||||
|
||||
SimpleTest.typeOf = function (object) {
|
||||
var c = Object.prototype.toString.apply(object);
|
||||
var name = c.substring(8, c.length - 1);
|
||||
if (name != 'Object') return name;
|
||||
// It may be a non-core class. Try to extract the class name from
|
||||
// the constructor function. This may not work in all implementations.
|
||||
if (/function ([^(\s]+)/.test(Function.toString.call(object.constructor))) {
|
||||
return RegExp.$1;
|
||||
}
|
||||
// No idea. :-(
|
||||
return name;
|
||||
};
|
||||
|
||||
SimpleTest.isa = function (object, clas) {
|
||||
return SimpleTest.typeOf(object) == clas;
|
||||
};
|
||||
|
||||
// Global symbols:
|
||||
var ok = SimpleTest.ok;
|
||||
var is = SimpleTest.is;
|
||||
var isDeeply = SimpleTest.isDeeply;
|
|
@ -0,0 +1,177 @@
|
|||
/**
|
||||
* TestRunner: A test runner for SimpleTest
|
||||
* TODO:
|
||||
*
|
||||
* * Avoid moving iframes: That causes reloads on mozilla and opera.
|
||||
*
|
||||
*
|
||||
**/
|
||||
var TestRunner = {};
|
||||
TestRunner.logEnabled = false;
|
||||
TestRunner._iframes = {};
|
||||
TestRunner._iframeDocuments = {};
|
||||
TestRunner._iframeRows = {};
|
||||
TestRunner._currentTest = 0;
|
||||
TestRunner._urls = [];
|
||||
TestRunner._testsDiv = DIV();
|
||||
TestRunner._progressDiv = DIV();
|
||||
TestRunner._summaryDiv = DIV(null,
|
||||
H1(null, "Tests Summary"),
|
||||
TABLE(null,
|
||||
THEAD(null,
|
||||
TR(null,
|
||||
TH(null, "Test"),
|
||||
TH(null, "Passed"),
|
||||
TH(null, "Failed")
|
||||
)
|
||||
),
|
||||
TBODY()
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* This function is called after generating the summary.
|
||||
**/
|
||||
TestRunner.onComplete = null;
|
||||
|
||||
/**
|
||||
* If logEnabled is true, this is the logger that will be used.
|
||||
**/
|
||||
TestRunner.logger = MochiKit.Logging.logger;
|
||||
|
||||
/**
|
||||
* Toggle element visibility
|
||||
**/
|
||||
TestRunner._toggle = function(el) {
|
||||
if (el.className == "noshow") {
|
||||
el.className = "";
|
||||
el.style.cssText = "";
|
||||
} else {
|
||||
el.className = "noshow";
|
||||
el.style.cssText = "width:0px; height:0px; border:0px;";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the iframe that contains a test
|
||||
**/
|
||||
TestRunner._makeIframe = function (url) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.src = url;
|
||||
iframe.name = url;
|
||||
iframe.width = "500";
|
||||
var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
|
||||
var tr = TR(null, TD({'colspan': '3'}, iframe));
|
||||
iframe._row = tr;
|
||||
tbody.appendChild(tr);
|
||||
return iframe;
|
||||
};
|
||||
|
||||
/**
|
||||
* TestRunner entry point.
|
||||
*
|
||||
* The arguments are the URLs of the test to be ran.
|
||||
*
|
||||
**/
|
||||
TestRunner.runTests = function (/*url...*/) {
|
||||
if (TestRunner.logEnabled)
|
||||
TestRunner.logger.log("SimpleTest START");
|
||||
|
||||
var body = document.getElementsByTagName("body")[0];
|
||||
appendChildNodes(body,
|
||||
TestRunner._testsDiv,
|
||||
TestRunner._progressDiv,
|
||||
TestRunner._summaryDiv
|
||||
);
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
TestRunner._urls.push(arguments[i]);
|
||||
}
|
||||
TestRunner.runNextTest();
|
||||
};
|
||||
|
||||
/**
|
||||
* Run the next test. If no test remains, calls makeSummary
|
||||
**/
|
||||
TestRunner.runNextTest = function() {
|
||||
if (TestRunner._currentTest < TestRunner._urls.length) {
|
||||
var url = TestRunner._urls[TestRunner._currentTest];
|
||||
var progress = SPAN(null,
|
||||
"Running ", A({href:url}, url), "..."
|
||||
);
|
||||
|
||||
if (TestRunner.logEnabled)
|
||||
TestRunner.logger.log(scrapeText(progress));
|
||||
|
||||
TestRunner._progressDiv.appendChild(progress);
|
||||
TestRunner._iframes[url] = TestRunner._makeIframe(url);
|
||||
} else {
|
||||
TestRunner.makeSummary();
|
||||
if (TestRunner.onComplete)
|
||||
TestRunner.onComplete();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This stub is called by SimpleTest when a test is finished.
|
||||
**/
|
||||
TestRunner.testFinished = function (doc) {
|
||||
appendChildNodes(TestRunner._progressDiv, SPAN(null, "Done"), BR());
|
||||
var finishedURL = TestRunner._urls[TestRunner._currentTest];
|
||||
|
||||
if (TestRunner.logEnabled)
|
||||
TestRunner.logger.debug("SimpleTest finished " + finishedURL);
|
||||
|
||||
TestRunner._iframeDocuments[finishedURL] = doc;
|
||||
// TestRunner._iframes[finishedURL].style.display = "none";
|
||||
TestRunner._toggle(TestRunner._iframes[finishedURL]);
|
||||
TestRunner._currentTest++;
|
||||
TestRunner.runNextTest();
|
||||
};
|
||||
|
||||
/**
|
||||
* Display the summary in the browser
|
||||
**/
|
||||
TestRunner.makeSummary = function() {
|
||||
if (TestRunner.logEnabled)
|
||||
TestRunner.logger.log("SimpleTest FINISHED");
|
||||
var rows = [];
|
||||
for (var url in TestRunner._iframeDocuments) {
|
||||
var doc = TestRunner._iframeDocuments[url];
|
||||
var nOK = withDocument(doc,
|
||||
partial(getElementsByTagAndClassName, 'div', 'test_ok')
|
||||
).length;
|
||||
var nNotOK = withDocument(doc,
|
||||
partial(getElementsByTagAndClassName, 'div', 'test_not_ok')
|
||||
).length;
|
||||
var toggle = partial(TestRunner._toggle, TestRunner._iframes[url]);
|
||||
var jsurl = "TestRunner._toggle(TestRunner._iframes['" + url + "'])";
|
||||
var row = TR(
|
||||
{'style': {'backgroundColor': nNotOK > 0 ? "#f00":"#0f0"}},
|
||||
TD(null, url),
|
||||
TD(null, nOK),
|
||||
TD(null, nNotOK)
|
||||
);
|
||||
row.onclick = toggle;
|
||||
var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
|
||||
tbody.insertBefore(row, TestRunner._iframes[url]._row)
|
||||
}
|
||||
};
|
||||
|
||||
if ( parent.SimpleTest && parent.runAJAXTest ) {
|
||||
TestRunner.makeSummary = function() {
|
||||
for (var url in TestRunner._iframeDocuments) {
|
||||
var doc = TestRunner._iframeDocuments[url];
|
||||
|
||||
var OK = withDocument(doc, partial(getElementsByTagAndClassName, 'div', 'test_ok'));
|
||||
for ( var i = 0; i < OK.length; i++ )
|
||||
parent.SimpleTest.ok( true, OK[i].innerHTML );
|
||||
|
||||
var NotOK = withDocument(doc, partial(getElementsByTagAndClassName, 'div', 'test_not_ok'));
|
||||
for ( var i = 0; i < NotOK.length; i++ )
|
||||
parent.SimpleTest.ok( false, NotOK[i].innerHTML );
|
||||
}
|
||||
|
||||
parent.runAJAXTest();
|
||||
};
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
.test_ok {
|
||||
color: green;
|
||||
display: none;
|
||||
}
|
||||
.test_not_ok {
|
||||
color: red;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.test_ok, .test_not_ok {
|
||||
border-bottom-width: 2px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: black;
|
||||
}
|
||||
|
||||
.all_pass {
|
||||
background-color: lime;
|
||||
}
|
||||
|
||||
.some_fail {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.tests_report {
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
width: 20em;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
MochiKit = {__export__: true};
|
||||
load('tests/FakeJSAN.js')
|
||||
JSAN.use('MochiKit.MockDOM');
|
||||
var window = this;
|
||||
var document = MochiKit.MockDOM.document;
|
||||
JSAN.use('MochiKit.MochiKit');
|
|
@ -0,0 +1,25 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="SimpleTest/TestRunner.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
TestRunner.runTests(
|
||||
'MochiKit-Async.html',
|
||||
'MochiKit-Base.html',
|
||||
'MochiKit-DateTime.html',
|
||||
'MochiKit-DOM.html',
|
||||
'MochiKit-Style.html',
|
||||
'MochiKit-Format.html',
|
||||
'MochiKit-Iter.html',
|
||||
'MochiKit-Logging.html',
|
||||
'MochiKit-MochiKit.html',
|
||||
'MochiKit-Color.html',
|
||||
'MochiKit-Selector.html',
|
||||
'MochiKit-Signal.html',
|
||||
'MochiKit-Visual.html'
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
load('tests/cli.js');
|
||||
|
||||
JSAN.use('MochiKit.Test');
|
||||
|
||||
print("[[ MochiKit.Base ]]");
|
||||
runTests('tests.test_Base');
|
||||
print("[[ MochiKit.Color ]]");
|
||||
runTests('tests.test_Color');
|
||||
print("[[ MochiKit.DateTime ]]");
|
||||
runTests('tests.test_DateTime');
|
||||
print("[[ MochiKit.Format ]]");
|
||||
runTests('tests.test_Format');
|
||||
print("[[ MochiKit.Iter ]]");
|
||||
runTests('tests.test_Iter');
|
||||
print("[[ MochiKit.Logging ]]");
|
||||
runTests('tests.test_Logging');
|
|
@ -0,0 +1,509 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Base'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Base'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_Base = function (t) {
|
||||
// test bind
|
||||
var not_self = {"toString": function () { return "not self"; } };
|
||||
var self = {"toString": function () { return "self"; } };
|
||||
var func = function (arg) { return this.toString() + " " + arg; };
|
||||
var boundFunc = bind(func, self);
|
||||
not_self.boundFunc = boundFunc;
|
||||
|
||||
t.is( isEmpty([], [], ""), true, "isEmpty true" )
|
||||
t.is( isEmpty([], [1], ""), true, "isEmpty true" )
|
||||
t.is( isNotEmpty([], [], ""), false, "isNotEmpty false" )
|
||||
t.is( isNotEmpty([], [1], ""), false, "isNotEmpty false" )
|
||||
|
||||
t.is( isEmpty([1], [1], "1"), false, "isEmpty false" )
|
||||
t.is( isEmpty([1], [1], "1"), false, "isEmpty false" )
|
||||
t.is( isNotEmpty([1], [1], "1"), true, "isNotEmpty true" )
|
||||
t.is( isNotEmpty([1], [1], "1"), true, "isNotEmpty true" )
|
||||
|
||||
t.is( boundFunc("foo"), "self foo", "boundFunc bound to self properly" );
|
||||
t.is( not_self.boundFunc("foo"), "self foo", "boundFunc bound to self on another obj" );
|
||||
t.is( bind(boundFunc, not_self)("foo"), "not self foo", "boundFunc successfully rebound!" );
|
||||
t.is( bind(boundFunc, undefined, "foo")(), "self foo", "boundFunc partial no self change" );
|
||||
t.is( bind(boundFunc, not_self, "foo")(), "not self foo", "boundFunc partial self change" );
|
||||
|
||||
// test method
|
||||
not_self = {"toString": function () { return "not self"; } };
|
||||
self = {"toString": function () { return "self"; } };
|
||||
func = function (arg) { return this.toString() + " " + arg; };
|
||||
var boundMethod = method(self, func);
|
||||
not_self.boundMethod = boundMethod;
|
||||
|
||||
t.is( boundMethod("foo"), "self foo", "boundMethod bound to self properly" );
|
||||
t.is( not_self.boundMethod("foo"), "self foo", "boundMethod bound to self on another obj" );
|
||||
t.is( method(not_self, boundMethod)("foo"), "not self foo", "boundMethod successfully rebound!" );
|
||||
t.is( method(undefined, boundMethod, "foo")(), "self foo", "boundMethod partial no self change" );
|
||||
t.is( method(not_self, boundMethod, "foo")(), "not self foo", "boundMethod partial self change" );
|
||||
|
||||
|
||||
|
||||
|
||||
// test bindMethods
|
||||
|
||||
var O = function (value) {
|
||||
bindMethods(this);
|
||||
this.value = value;
|
||||
};
|
||||
O.prototype.func = function () {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
var o = new O("boring");
|
||||
var p = {};
|
||||
p.func = o.func;
|
||||
var func = o.func;
|
||||
t.is( o.func(), "boring", "bindMethods doesn't break shit" );
|
||||
t.is( p.func(), "boring", "bindMethods works on other objects" );
|
||||
t.is( func(), "boring", "bindMethods works on functions" );
|
||||
|
||||
var p = clone(o);
|
||||
t.ok( p instanceof O, "cloned correct inheritance" );
|
||||
var q = clone(p);
|
||||
t.ok( q instanceof O, "clone-cloned correct inheritance" );
|
||||
q.foo = "bar";
|
||||
t.is( p.foo, undefined, "clone-clone is copy-on-write" );
|
||||
p.bar = "foo";
|
||||
t.is( o.bar, undefined, "clone is copy-on-write" );
|
||||
t.is( q.bar, "foo", "clone-clone has proper delegation" );
|
||||
// unbind
|
||||
p.func = bind(p.func, null);
|
||||
t.is( p.func(), "boring", "clone function calls correct" );
|
||||
q.value = "awesome";
|
||||
t.is( q.func(), "awesome", "clone really does work" );
|
||||
|
||||
// test boring boolean funcs
|
||||
|
||||
t.is( isCallable(isCallable), true, "isCallable returns true on itself" );
|
||||
t.is( isCallable(1), false, "isCallable returns false on numbers" );
|
||||
|
||||
t.is( isUndefined(null), false, "null is not undefined" );
|
||||
t.is( isUndefined(""), false, "empty string is not undefined" );
|
||||
t.is( isUndefined(undefined), true, "undefined is undefined" );
|
||||
t.is( isUndefined({}.foo), true, "missing property is undefined" );
|
||||
|
||||
t.is( isUndefinedOrNull(null), true, "null is undefined or null" );
|
||||
t.is( isUndefinedOrNull(""), false, "empty string is not undefined or null" );
|
||||
t.is( isUndefinedOrNull(undefined), true, "undefined is undefined or null" );
|
||||
t.is( isUndefinedOrNull({}.foo), true, "missing property is undefined or null" );
|
||||
|
||||
// test extension of arrays
|
||||
var a = [];
|
||||
var b = [];
|
||||
var three = [1, 2, 3];
|
||||
|
||||
extend(a, three, 1);
|
||||
t.ok( objEqual(a, [2, 3]), "extend to an empty array" );
|
||||
extend(a, three, 1)
|
||||
t.ok( objEqual(a, [2, 3, 2, 3]), "extend to a non-empty array" );
|
||||
|
||||
extend(b, three);
|
||||
t.ok( objEqual(b, three), "extend of an empty array" );
|
||||
|
||||
t.is( compare(1, 2), -1, "numbers compare lt" );
|
||||
t.is( compare(2, 1), 1, "numbers compare gt" );
|
||||
t.is( compare(1, 1), 0, "numbers compare eq" );
|
||||
t.is( compare([1], [1]), 0, "arrays compare eq" );
|
||||
t.is( compare([1], [1, 2]), -1, "arrays compare lt (length)" );
|
||||
t.is( compare([1, 2], [2, 1]), -1, "arrays compare lt (contents)" );
|
||||
t.is( compare([1, 2], [1]), 1, "arrays compare gt (length)" );
|
||||
t.is( compare([2, 1], [1, 1]), 1, "arrays compare gt (contents)" );
|
||||
|
||||
// test partial application
|
||||
var a = [];
|
||||
var func = function (a, b) {
|
||||
if (arguments.length != 2) {
|
||||
return "bad args";
|
||||
} else {
|
||||
return this.value + a + b;
|
||||
}
|
||||
};
|
||||
var self = {"value": 1, "func": func};
|
||||
var self2 = {"value": 2};
|
||||
t.is( self.func(2, 3), 6, "setup for test is correct" );
|
||||
self.funcTwo = partial(self.func, 2);
|
||||
t.is( self.funcTwo(3), 6, "partial application works" );
|
||||
t.is( self.funcTwo(3), 6, "partial application works still" );
|
||||
t.is( bind(self.funcTwo, self2)(3), 7, "rebinding partial works" );
|
||||
self.funcTwo = bind(bind(self.funcTwo, self2), null);
|
||||
t.is( self.funcTwo(3), 6, "re-unbinding partial application works" );
|
||||
|
||||
|
||||
// nodeWalk test
|
||||
// ... looks a lot like a DOM tree on purpose
|
||||
var tree = {
|
||||
"id": "nodeWalkTestTree",
|
||||
"test:int": "1",
|
||||
"childNodes": [
|
||||
{
|
||||
"test:int": "2",
|
||||
"childNodes": [
|
||||
{"test:int": "5"},
|
||||
"ignored string",
|
||||
{"ignored": "object"},
|
||||
["ignored", "list"],
|
||||
{
|
||||
"test:skipchildren": "1",
|
||||
"childNodes": [{"test:int": 6}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{"test:int": "3"},
|
||||
{"test:int": "4"}
|
||||
]
|
||||
}
|
||||
|
||||
var visitedNodes = [];
|
||||
nodeWalk(tree, function (node) {
|
||||
var attr = node["test:int"];
|
||||
if (attr) {
|
||||
visitedNodes.push(attr);
|
||||
}
|
||||
if (node["test:skipchildren"]) {
|
||||
return;
|
||||
}
|
||||
return node.childNodes;
|
||||
});
|
||||
|
||||
t.ok( objEqual(visitedNodes, ["1", "2", "3", "4", "5"]), "nodeWalk looks like it works");
|
||||
|
||||
// test map
|
||||
var minusOne = function (x) { return x - 1; };
|
||||
var res = map(minusOne, [1, 2, 3]);
|
||||
t.ok( objEqual(res, [0, 1, 2]), "map works" );
|
||||
|
||||
var res2 = xmap(minusOne, 1, 2, 3);
|
||||
t.ok( objEqual(res2, res), "xmap works" );
|
||||
|
||||
res = map(operator.add, [1, 2, 3], [2, 4, 6]);
|
||||
t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works" );
|
||||
|
||||
res = map(operator.add, [1, 2, 3], [2, 4, 6, 8]);
|
||||
t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works (q long)" );
|
||||
|
||||
res = map(operator.add, [1, 2, 3, 4], [2, 4, 6]);
|
||||
t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works (p long)" );
|
||||
|
||||
res = map(null, [1, 2, 3], [2, 4, 6]);
|
||||
t.ok( objEqual(res, [[1, 2], [2, 4], [3, 6]]), "map(null, p, q) works" );
|
||||
|
||||
res = zip([1, 2, 3], [2, 4, 6]);
|
||||
t.ok( objEqual(res, [[1, 2], [2, 4], [3, 6]]), "zip(p, q) works" );
|
||||
|
||||
res = map(null, [1, 2, 3]);
|
||||
t.ok( objEqual(res, [1, 2, 3]), "map(null, lst) works" );
|
||||
|
||||
|
||||
|
||||
|
||||
t.is( isNotEmpty("foo"), true, "3 char string is not empty" );
|
||||
t.is( isNotEmpty(""), false, "0 char string is empty" );
|
||||
t.is( isNotEmpty([1, 2, 3]), true, "3 element list is not empty" );
|
||||
t.is( isNotEmpty([]), false, "0 element list is empty" );
|
||||
|
||||
// test filter
|
||||
var greaterThanThis = function (x) { return x > this; };
|
||||
var greaterThanOne = function (x) { return x > 1; };
|
||||
var res = filter(greaterThanOne, [-1, 0, 1, 2, 3]);
|
||||
t.ok( objEqual(res, [2, 3]), "filter works" );
|
||||
var res = filter(greaterThanThis, [-1, 0, 1, 2, 3], 1);
|
||||
t.ok( objEqual(res, [2, 3]), "filter self works" );
|
||||
var res2 = xfilter(greaterThanOne, -1, 0, 1, 2, 3);
|
||||
t.ok( objEqual(res2, res), "xfilter works" );
|
||||
|
||||
t.is(objMax(1, 2, 9, 12, 42, -16, 16), 42, "objMax works (with numbers)");
|
||||
t.is(objMin(1, 2, 9, 12, 42, -16, 16), -16, "objMin works (with numbers)");
|
||||
|
||||
// test adapter registry
|
||||
|
||||
var R = new AdapterRegistry();
|
||||
R.register("callable", isCallable, function () { return "callable"; });
|
||||
R.register("arrayLike", isArrayLike, function () { return "arrayLike"; });
|
||||
t.is( R.match(function () {}), "callable", "registry found callable" );
|
||||
t.is( R.match([]), "arrayLike", "registry found ArrayLike" );
|
||||
try {
|
||||
R.match(null);
|
||||
t.ok( false, "non-matching didn't raise!" );
|
||||
} catch (e) {
|
||||
t.is( e, NotFound, "non-matching raised correctly" );
|
||||
}
|
||||
R.register("undefinedOrNull", isUndefinedOrNull, function () { return "undefinedOrNull" });
|
||||
R.register("undefined", isUndefined, function () { return "undefined" });
|
||||
t.is( R.match(undefined), "undefinedOrNull", "priorities are as documented" );
|
||||
t.ok( R.unregister("undefinedOrNull"), "removed adapter" );
|
||||
t.is( R.match(undefined), "undefined", "adapter was removed" );
|
||||
R.register("undefinedOrNull", isUndefinedOrNull, function () { return "undefinedOrNull" }, true);
|
||||
t.is( R.match(undefined), "undefinedOrNull", "override works" );
|
||||
|
||||
var a1 = {"a": 1, "b": 2, "c": 2};
|
||||
var a2 = {"a": 2, "b": 1, "c": 2};
|
||||
t.is( keyComparator("a")(a1, a2), -1, "keyComparator 1 lt" );
|
||||
t.is( keyComparator("c")(a1, a2), 0, "keyComparator 1 eq" );
|
||||
t.is( keyComparator("c", "b")(a1, a2), 1, "keyComparator 2 eq gt" );
|
||||
t.is( keyComparator("c", "a")(a1, a2), -1, "keyComparator 2 eq lt" );
|
||||
t.is( reverseKeyComparator("a")(a1, a2), 1, "reverseKeyComparator" );
|
||||
t.is( compare(concat([1], [2], [3]), [1, 2, 3]), 0, "concat" );
|
||||
t.is( repr("foo"), '"foo"', "string repr" );
|
||||
t.is( repr(1), '1', "number repr" );
|
||||
t.is( listMin([1, 3, 5, 3, -1]), -1, "listMin" );
|
||||
t.is( objMin(1, 3, 5, 3, -1), -1, "objMin" );
|
||||
t.is( listMax([1, 3, 5, 3, -1]), 5, "listMax" );
|
||||
t.is( objMax(1, 3, 5, 3, -1), 5, "objMax" );
|
||||
|
||||
var v = keys(a1);
|
||||
v.sort();
|
||||
t.is( compare(v, ["a", "b", "c"]), 0, "keys" );
|
||||
v = items(a1);
|
||||
v.sort();
|
||||
t.is( compare(v, [["a", 1], ["b", 2], ["c", 2]]), 0, "items" );
|
||||
|
||||
var StringMap = function() {};
|
||||
a = new StringMap();
|
||||
a.foo = "bar";
|
||||
b = new StringMap();
|
||||
b.foo = "bar";
|
||||
try {
|
||||
compare(a, b);
|
||||
t.ok( false, "bad comparison registered!?" );
|
||||
} catch (e) {
|
||||
t.ok( e instanceof TypeError, "bad comparison raised TypeError" );
|
||||
}
|
||||
|
||||
t.is( repr(a), "[object Object]", "default repr for StringMap" );
|
||||
var isStringMap = function () {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
if (!(arguments[i] instanceof StringMap)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
registerRepr("stringMap",
|
||||
isStringMap,
|
||||
function (obj) {
|
||||
return "StringMap(" + repr(items(obj)) + ")";
|
||||
}
|
||||
);
|
||||
|
||||
t.is( repr(a), 'StringMap([["foo", "bar"]])', "repr worked" );
|
||||
|
||||
// not public API
|
||||
MochiKit.Base.reprRegistry.unregister("stringMap");
|
||||
|
||||
t.is( repr(a), "[object Object]", "default repr for StringMap" );
|
||||
|
||||
registerComparator("stringMap",
|
||||
isStringMap,
|
||||
function (a, b) {
|
||||
// no sorted(...) in base
|
||||
a = items(a);
|
||||
b = items(b);
|
||||
a.sort(compare);
|
||||
b.sort(compare);
|
||||
return compare(a, b);
|
||||
}
|
||||
);
|
||||
|
||||
t.is( compare(a, b), 0, "registerComparator" );
|
||||
|
||||
update(a, {"foo": "bar"}, {"wibble": "baz"}, undefined, null, {"grr": 1});
|
||||
t.is( a.foo, "bar", "update worked (first obj)" );
|
||||
t.is( a.wibble, "baz", "update worked (second obj)" );
|
||||
t.is( a.grr, 1, "update worked (skipped undefined and null)" );
|
||||
t.is( compare(a, b), 1, "update worked (comparison)" );
|
||||
|
||||
|
||||
setdefault(a, {"foo": "unf"}, {"bar": "web taco"} );
|
||||
t.is( a.foo, "bar", "setdefault worked (skipped existing)" );
|
||||
t.is( a.bar, "web taco", "setdefault worked (set non-existing)" );
|
||||
|
||||
var c = items(merge({"foo": "bar"}, {"wibble": "baz"}));
|
||||
c.sort(compare);
|
||||
t.is( compare(c, [["foo", "bar"], ["wibble", "baz"]]), 0, "merge worked" );
|
||||
|
||||
// not public API
|
||||
MochiKit.Base.comparatorRegistry.unregister("stringMap");
|
||||
|
||||
try {
|
||||
compare(a, b);
|
||||
t.ok( false, "bad comparison registered!?" );
|
||||
} catch (e) {
|
||||
t.ok( e instanceof TypeError, "bad comparison raised TypeError" );
|
||||
}
|
||||
|
||||
var o = {"__repr__": function () { return "__repr__"; }};
|
||||
t.is( repr(o), "__repr__", "__repr__ protocol" );
|
||||
t.is( repr(MochiKit.Base), MochiKit.Base.__repr__(), "__repr__ protocol when repr is defined" );
|
||||
var o = {"NAME": "NAME"};
|
||||
t.is( repr(o), "NAME", "NAME protocol (obj)" );
|
||||
o = function () { return "TACO" };
|
||||
o.NAME = "NAME";
|
||||
t.is( repr(o), "NAME", "NAME protocol (func)" );
|
||||
|
||||
t.is( repr(MochiKit.Base.nameFunctions), "MochiKit.Base.nameFunctions", "test nameFunctions" );
|
||||
// Done!
|
||||
|
||||
t.is( urlEncode("1+2=2").toUpperCase(), "1%2B2%3D2", "urlEncode" );
|
||||
t.is( queryString(["a", "b"], [1, "two"]), "a=1&b=two", "queryString");
|
||||
t.is( queryString({"a": 1}), "a=1", "one item alternate form queryString" );
|
||||
var o = {"a": 1, "b": 2, "c": function() {}};
|
||||
var res = queryString(o).split("&");
|
||||
res.sort();
|
||||
t.is( res.join("&"), "a=1&b=2", "two item alternate form queryString, function skip" );
|
||||
var res = parseQueryString("1+1=2&b=3%3D2");
|
||||
t.is( res["1 1"], "2", "parseQueryString pathological name" );
|
||||
t.is( res.b, "3=2", "parseQueryString second name:value pair" );
|
||||
var res = parseQueryString("foo=one&foo=two", true);
|
||||
t.is( res["foo"].join(" "), "one two", "parseQueryString useArrays" );
|
||||
var res = parseQueryString("?foo=2&bar=1");
|
||||
t.is( res["foo"], "2", "parseQueryString strip leading question mark");
|
||||
|
||||
t.is( serializeJSON("foo\n\r\b\f\t"), "\"foo\\n\\r\\b\\f\\t\"", "string JSON" );
|
||||
t.is( serializeJSON(null), "null", "null JSON");
|
||||
try {
|
||||
serializeJSON(undefined);
|
||||
t.ok(false, "undefined should not be serializable");
|
||||
} catch (e) {
|
||||
t.ok(e instanceof TypeError, "undefined not serializable");
|
||||
}
|
||||
t.is( serializeJSON(1), "1", "1 JSON");
|
||||
t.is( serializeJSON(1.23), "1.23", "1.23 JSON");
|
||||
t.is( serializeJSON(serializeJSON), null, "function JSON (null, not string)" );
|
||||
t.is( serializeJSON([1, "2", 3.3]), "[1, \"2\", 3.3]", "array JSON" );
|
||||
var res = evalJSON(serializeJSON({"a":1, "b":2}));
|
||||
t.is( res.a, 1, "evalJSON on an object (1)" );
|
||||
t.is( res.b, 2, "evalJSON on an object (2)" );
|
||||
var res = {"a": 1, "b": 2, "json": function () { return this; }};
|
||||
var res = evalJSON(serializeJSON(res));
|
||||
t.is( res.a, 1, "evalJSON on an object that jsons self (1)" );
|
||||
t.is( res.b, 2, "evalJSON on an object that jsons self (2)" );
|
||||
var strJSON = {"a": 1, "b": 2, "json": function () { return "json"; }};
|
||||
t.is( serializeJSON(strJSON), "\"json\"", "json serialization calling" );
|
||||
t.is( serializeJSON([strJSON]), "[\"json\"]", "json serialization calling in a structure" );
|
||||
t.is( evalJSON('/* {"result": 1} */').result, 1, "json comment stripping" );
|
||||
t.is( evalJSON('/* {"*/ /*": 1} */')['*/ /*'], 1, "json comment stripping" );
|
||||
registerJSON("isDateLike",
|
||||
isDateLike,
|
||||
function (d) {
|
||||
return "this was a date";
|
||||
}
|
||||
);
|
||||
t.is( serializeJSON(new Date()), "\"this was a date\"", "json registry" );
|
||||
MochiKit.Base.jsonRegistry.unregister("isDateLike");
|
||||
|
||||
var a = {"foo": {"bar": 12, "wibble": 13}};
|
||||
var b = {"foo": {"baz": 4, "bar": 16}, "bar": 4};
|
||||
updatetree(a, b);
|
||||
var expect = [["bar", 16], ["baz", 4], ["wibble", 13]];
|
||||
var got = items(a.foo);
|
||||
got.sort(compare);
|
||||
t.is( repr(got), repr(expect), "updatetree merge" );
|
||||
t.is( a.bar, 4, "updatetree insert" );
|
||||
|
||||
var c = counter();
|
||||
t.is( c(), 1, "counter starts at 1" );
|
||||
t.is( c(), 2, "counter increases" );
|
||||
c = counter(2);
|
||||
t.is( c(), 2, "counter starts at 2" );
|
||||
t.is( c(), 3, "counter increases" );
|
||||
|
||||
t.is( findValue([1, 2, 3], 4), -1, "findValue returns -1 on not found");
|
||||
t.is( findValue([1, 2, 3], 1), 0, "findValue returns correct index");
|
||||
t.is( findValue([1, 2, 3], 1, 1), -1, "findValue honors start");
|
||||
t.is( findValue([1, 2, 3], 2, 0, 1), -1, "findValue honors end");
|
||||
t.is( findIdentical([1, 2, 3], 4), -1, "findIdentical returns -1");
|
||||
t.is( findIdentical([1, 2, 3], 1), 0, "findIdentical returns correct index");
|
||||
t.is( findIdentical([1, 2, 3], 1, 1), -1, "findIdentical honors start");
|
||||
t.is( findIdentical([1, 2, 3], 2, 0, 1), -1, "findIdentical honors end");
|
||||
t.is( isNull(undefined), false, "isNull doesn't match undefined" );
|
||||
|
||||
var flat = flattenArguments(1, "2", 3, [4, [5, [6, 7], 8, [], 9]]);
|
||||
var expect = [1, "2", 3, 4, 5, 6, 7, 8, 9];
|
||||
t.is( repr(flat), repr(expect), "flattenArguments" );
|
||||
|
||||
var fn = function () {
|
||||
return [this, concat(arguments)];
|
||||
}
|
||||
t.is( methodcaller("toLowerCase")("FOO"), "foo", "methodcaller with a method name" );
|
||||
t.is( repr(methodcaller(fn, 2, 3)(1)), "[1, [2, 3]]", "methodcaller with a function" );
|
||||
|
||||
var f1 = function (x) { return [1, x]; };
|
||||
var f2 = function (x) { return [2, x]; };
|
||||
var f3 = function (x) { return [3, x]; };
|
||||
t.is( repr(f1(f2(f3(4)))), "[1, [2, [3, 4]]]", "test the compose test" );
|
||||
t.is( repr(compose(f1,f2,f3)(4)), "[1, [2, [3, 4]]]", "three fn composition works" );
|
||||
t.is( repr(compose(compose(f1,f2),f3)(4)), "[1, [2, [3, 4]]]", "associative left" );
|
||||
t.is( repr(compose(f1,compose(f2,f3))(4)), "[1, [2, [3, 4]]]", "associative right" );
|
||||
|
||||
try {
|
||||
compose(f1, "foo");
|
||||
t.ok( false, "wrong compose argument not raised!" );
|
||||
} catch (e) {
|
||||
t.is( e.name, 'TypeError', "wrong compose argument raised correctly" );
|
||||
}
|
||||
|
||||
t.is(camelize('one'), 'one', 'one word');
|
||||
t.is(camelize('one-two'), 'oneTwo', 'two words');
|
||||
t.is(camelize('one-two-three'), 'oneTwoThree', 'three words');
|
||||
t.is(camelize('1-one'), '1One', 'letter and word');
|
||||
t.is(camelize('one-'), 'one', 'trailing hyphen');
|
||||
t.is(camelize('-one'), 'One', 'starting hyphen');
|
||||
t.is(camelize('o-two'), 'oTwo', 'one character and word');
|
||||
|
||||
var flat = flattenArray([1, "2", 3, [4, [5, [6, 7], 8, [], 9]]]);
|
||||
var expect = [1, "2", 3, 4, 5, 6, 7, 8, 9];
|
||||
t.is( repr(flat), repr(expect), "flattenArray" );
|
||||
|
||||
/* mean */
|
||||
try {
|
||||
mean();
|
||||
t.ok( false, "no arguments didn't raise!" );
|
||||
} catch (e) {
|
||||
t.is( e.name, 'TypeError', "no arguments raised correctly" );
|
||||
}
|
||||
t.is( mean(1), 1, 'single argument (arg list)');
|
||||
t.is( mean([1]), 1, 'single argument (array)');
|
||||
t.is( mean(1,2,3), 2, 'three arguments (arg list)');
|
||||
t.is( mean([1,2,3]), 2, 'three arguments (array)');
|
||||
t.is( average(1), 1, 'test the average alias');
|
||||
|
||||
/* median */
|
||||
try {
|
||||
median();
|
||||
t.ok( false, "no arguments didn't raise!" );
|
||||
} catch (e) {
|
||||
t.is( e.name, 'TypeError', "no arguments raised correctly" );
|
||||
}
|
||||
t.is( median(1), 1, 'single argument (arg list)');
|
||||
t.is( median([1]), 1, 'single argument (array)');
|
||||
t.is( median(3,1,2), 2, 'three arguments (arg list)');
|
||||
t.is( median([3,1,2]), 2, 'three arguments (array)');
|
||||
t.is( median(3,1,2,4), 2.5, 'four arguments (arg list)');
|
||||
t.is( median([3,1,2,4]), 2.5, 'four arguments (array)');
|
||||
|
||||
/* #185 */
|
||||
t.is( serializeJSON(parseQueryString("")), "{}", "parseQueryString('')" );
|
||||
t.is( serializeJSON(parseQueryString("", true)), "{}", "parseQueryString('', true)" );
|
||||
|
||||
/* #109 */
|
||||
t.is( queryString({ids: [1,2,3]}), "ids=1&ids=2&ids=3", "queryString array value" );
|
||||
t.is( queryString({ids: "123"}), "ids=123", "queryString string value" );
|
||||
|
||||
/* test values */
|
||||
var o = {a: 1, b: 2, c: 4, d: -1};
|
||||
var got = values(o);
|
||||
got.sort();
|
||||
t.is( repr(got), repr([-1, 1, 2, 4]), "values()" );
|
||||
|
||||
t.is( queryString([["foo", "bar"], ["baz", "wibble"]]), "foo=baz&bar=wibble" );
|
||||
o = parseQueryString("foo=1=1=1&bar=2&baz&wibble=");
|
||||
t.is( o.foo, "1=1=1", "parseQueryString multiple = first" );
|
||||
t.is( o.bar, "2", "parseQueryString multiple = second" );
|
||||
t.is( o.baz, "", "parseQueryString multiple = third" );
|
||||
t.is( o.wibble, "", "parseQueryString multiple = fourth" );
|
||||
|
||||
};
|
|
@ -0,0 +1,137 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Color'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Color'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_Color = function (t) {
|
||||
var approx = function (a, b, msg) {
|
||||
return t.is(a.toPrecision(4), b.toPrecision(4), msg);
|
||||
};
|
||||
|
||||
t.is( Color.whiteColor().toHexString(), "#ffffff", "whiteColor has right hex" );
|
||||
t.is( Color.blackColor().toHexString(), "#000000", "blackColor has right hex" );
|
||||
t.is( Color.blueColor().toHexString(), "#0000ff", "blueColor has right hex" );
|
||||
t.is( Color.redColor().toHexString(), "#ff0000", "redColor has right hex" );
|
||||
t.is( Color.greenColor().toHexString(), "#00ff00", "greenColor has right hex" );
|
||||
t.is( compare(Color.whiteColor(), Color.whiteColor()), 0, "default colors compare right" );
|
||||
t.ok( Color.whiteColor() == Color.whiteColor(), "default colors are interned" );
|
||||
t.ok( Color.whiteColor().toRGBString(), "rgb(255,255,255)", "toRGBString white" );
|
||||
t.ok( Color.blueColor().toRGBString(), "rgb(0,0,255)", "toRGBString blue" );
|
||||
t.is( Color.fromRGB(190/255, 222/255, 173/255).toHexString(), "#bedead", "fromRGB works" );
|
||||
t.is( Color.fromRGB(226/255, 15.9/255, 182/255).toHexString(), "#e210b6", "fromRGB < 16 works" );
|
||||
t.is( Color.fromRGB({r:190/255,g:222/255,b:173/255}).toHexString(), "#bedead", "alt fromRGB works" );
|
||||
t.is( Color.fromHexString("#bedead").toHexString(), "#bedead", "round-trip hex" );
|
||||
t.is( Color.fromString("#bedead").toHexString(), "#bedead", "round-trip string(hex)" );
|
||||
t.is( Color.fromRGBString("rgb(190,222,173)").toHexString(), "#bedead", "round-trip rgb" );
|
||||
t.is( Color.fromString("rgb(190,222,173)").toHexString(), "#bedead", "round-trip rgb" );
|
||||
|
||||
var hsl = Color.redColor().asHSL();
|
||||
approx( hsl.h, 0.0, "red hsl.h" );
|
||||
approx( hsl.s, 1.0, "red hsl.s" );
|
||||
approx( hsl.l, 0.5, "red hsl.l" );
|
||||
hsl = Color.fromRGB(0, 0, 0.5).asHSL();
|
||||
approx( hsl.h, 2/3, "darkblue hsl.h" );
|
||||
approx( hsl.s, 1.0, "darkblue hsl.s" );
|
||||
approx( hsl.l, 0.25, "darkblue hsl.l" );
|
||||
hsl = Color.fromString("#4169E1").asHSL();
|
||||
approx( hsl.h, (5/8), "4169e1 h");
|
||||
approx( hsl.s, (8/11), "4169e1 s");
|
||||
approx( hsl.l, (29/51), "4169e1 l");
|
||||
hsl = Color.fromString("#555544").asHSL();
|
||||
approx( hsl.h, (1/6), "555544 h" );
|
||||
approx( hsl.s, (1/9), "555544 s" );
|
||||
approx( hsl.l, (3/10), "555544 l" );
|
||||
hsl = Color.fromRGB(0.5, 1, 0.5).asHSL();
|
||||
approx( hsl.h, 1/3, "aqua hsl.h" );
|
||||
approx( hsl.s, 1.0, "aqua hsl.s" );
|
||||
approx( hsl.l, 0.75, "aqua hsl.l" );
|
||||
t.is(
|
||||
Color.fromHSL(hsl.h, hsl.s, hsl.l).toHexString(),
|
||||
Color.fromRGB(0.5, 1, 0.5).toHexString(),
|
||||
"fromHSL works with components"
|
||||
);
|
||||
t.is(
|
||||
Color.fromHSL(hsl).toHexString(),
|
||||
Color.fromRGB(0.5, 1, 0.5).toHexString(),
|
||||
"fromHSL alt form"
|
||||
);
|
||||
t.is(
|
||||
Color.fromString("hsl(120,100%,75%)").toHexString(),
|
||||
"#80ff80",
|
||||
"fromHSLString"
|
||||
);
|
||||
t.is(
|
||||
Color.fromRGB(0.5, 1, 0.5).toHSLString(),
|
||||
"hsl(120,100.0%,75.00%)",
|
||||
"toHSLString"
|
||||
);
|
||||
t.is( Color.fromHSL(0, 0, 0).toHexString(), "#000000", "fromHSL to black" );
|
||||
hsl = Color.blackColor().asHSL();
|
||||
approx( hsl.h, 0.0, "black hsl.h" );
|
||||
approx( hsl.s, 0.0, "black hsl.s" );
|
||||
approx( hsl.l, 0.0, "black hsl.l" );
|
||||
hsl.h = 1.0;
|
||||
hsl = Color.blackColor().asHSL();
|
||||
approx( hsl.h, 0.0, "asHSL returns copy" );
|
||||
var rgb = Color.brownColor().asRGB();
|
||||
approx( rgb.r, 153/255, "brown rgb.r" );
|
||||
approx( rgb.g, 102/255, "brown rgb.g" );
|
||||
approx( rgb.b, 51/255, "brown rgb.b" );
|
||||
rgb.r = 0;
|
||||
rgb = Color.brownColor().asRGB();
|
||||
approx( rgb.r, 153/255, "asRGB returns copy" );
|
||||
|
||||
t.is( Color.fromName("aqua").toHexString(), "#00ffff", "aqua fromName" );
|
||||
t.is( Color.fromString("aqua").toHexString(), "#00ffff", "aqua fromString" );
|
||||
t.is( Color.fromName("transparent"), Color.transparentColor(), "transparent fromName" );
|
||||
t.is( Color.fromString("transparent"), Color.transparentColor(), "transparent fromString" );
|
||||
t.is( Color.transparentColor().toRGBString(), "rgba(0,0,0,0)", "transparent toRGBString" );
|
||||
t.is( Color.fromRGBString("rgba( 0, 255, 255, 50%)").asRGB().a, 0.5, "rgba parsing alpha correctly" );
|
||||
t.is( Color.fromRGBString("rgba( 0, 255, 255, 50%)").toRGBString(), "rgba(0,255,255,0.5)", "rgba output correctly" );
|
||||
t.is( Color.fromRGBString("rgba( 0, 255, 255, 1)").toHexString(), "#00ffff", "fromRGBString with spaces and alpha" );
|
||||
t.is( Color.fromRGBString("rgb( 0, 255, 255)").toHexString(), "#00ffff", "fromRGBString with spaces" );
|
||||
t.is( Color.fromRGBString("rgb( 0, 100%, 255)").toHexString(), "#00ffff", "fromRGBString with percents" );
|
||||
|
||||
var hsv = Color.redColor().asHSV();
|
||||
approx( hsv.h, 0.0, "red hsv.h" );
|
||||
approx( hsv.s, 1.0, "red hsv.s" );
|
||||
approx( hsv.v, 1.0, "red hsv.v" );
|
||||
t.is( Color.fromHSV(hsv).toHexString(), Color.redColor().toHexString(), "red hexstring" );
|
||||
hsv = Color.fromRGB(0, 0, 0.5).asHSV();
|
||||
approx( hsv.h, 2/3, "darkblue hsv.h" );
|
||||
approx( hsv.s, 1.0, "darkblue hsv.s" );
|
||||
approx( hsv.v, 0.5, "darkblue hsv.v" );
|
||||
t.is( Color.fromHSV(hsv).toHexString(), Color.fromRGB(0, 0, 0.5).toHexString(), "darkblue hexstring" );
|
||||
hsv = Color.fromString("#4169E1").asHSV();
|
||||
approx( hsv.h, 5/8, "4169e1 h");
|
||||
approx( hsv.s, 32/45, "4169e1 s");
|
||||
approx( hsv.v, 15/17, "4169e1 l");
|
||||
t.is( Color.fromHSV(hsv).toHexString(), "#4169e1", "4169e1 hexstring" );
|
||||
hsv = Color.fromString("#555544").asHSV();
|
||||
approx( hsv.h, 1/6, "555544 h" );
|
||||
approx( hsv.s, 1/5, "555544 s" );
|
||||
approx( hsv.v, 1/3, "555544 l" );
|
||||
t.is( Color.fromHSV(hsv).toHexString(), "#555544", "555544 hexstring" );
|
||||
hsv = Color.fromRGB(0.5, 1, 0.5).asHSV();
|
||||
approx( hsv.h, 1/3, "aqua hsv.h" );
|
||||
approx( hsv.s, 0.5, "aqua hsv.s" );
|
||||
approx( hsv.v, 1, "aqua hsv.v" );
|
||||
t.is(
|
||||
Color.fromHSV(hsv.h, hsv.s, hsv.v).toHexString(),
|
||||
Color.fromRGB(0.5, 1, 0.5).toHexString(),
|
||||
"fromHSV works with components"
|
||||
);
|
||||
t.is(
|
||||
Color.fromHSV(hsv).toHexString(),
|
||||
Color.fromRGB(0.5, 1, 0.5).toHexString(),
|
||||
"fromHSV alt form"
|
||||
);
|
||||
hsv = Color.fromRGB(1, 1, 1).asHSV()
|
||||
approx( hsv.h, 0, 'white hsv.h' );
|
||||
approx( hsv.s, 0, 'white hsv.s' );
|
||||
approx( hsv.v, 1, 'white hsv.v' );
|
||||
t.is(
|
||||
Color.fromHSV(0, 0, 1).toHexString(),
|
||||
'#ffffff',
|
||||
'HSV saturation'
|
||||
);
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.DateTime'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.DateTime'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_DateTime = function (t) {
|
||||
var testDate = isoDate('2005-2-3');
|
||||
t.is(testDate.getFullYear(), 2005, "isoDate year ok");
|
||||
t.is(testDate.getDate(), 3, "isoDate day ok");
|
||||
t.is(testDate.getMonth(), 1, "isoDate month ok");
|
||||
t.ok(objEqual(testDate, new Date("February 3, 2005")), "matches string date");
|
||||
t.is(toISODate(testDate), '2005-02-03', 'toISODate ok');
|
||||
|
||||
var testDate = isoDate('2005-06-08');
|
||||
t.is(testDate.getFullYear(), 2005, "isoDate year ok");
|
||||
t.is(testDate.getDate(), 8, "isoDate day ok");
|
||||
t.is(testDate.getMonth(), 5, "isoDate month ok");
|
||||
t.ok(objEqual(testDate, new Date("June 8, 2005")), "matches string date");
|
||||
t.is(toISODate(testDate), '2005-06-08', 'toISODate ok');
|
||||
|
||||
t.is(compare(new Date("February 3, 2005"), new Date(2005, 1, 3)), 0, "dates compare eq");
|
||||
t.is(compare(new Date("February 3, 2005"), new Date(2005, 2, 3)), -1, "dates compare lt");
|
||||
t.is(compare(new Date("February 3, 2005"), new Date(2005, 0, 3)), 1, "dates compare gt");
|
||||
|
||||
var testDate = isoDate('2005-2-3');
|
||||
t.is(compare(americanDate('2/3/2005'), testDate), 0, "americanDate eq");
|
||||
t.is(compare('2/3/2005', toAmericanDate(testDate)), 0, "toAmericanDate eq");
|
||||
|
||||
var testTimestamp = isoTimestamp('2005-2-3 22:01:03');
|
||||
t.is(compare(testTimestamp, new Date(2005,1,3,22,1,3)), 0, "isoTimestamp eq");
|
||||
t.is(compare(testTimestamp, isoTimestamp('2005-2-3T22:01:03')), 0, "isoTimestamp (real ISO) eq");
|
||||
t.is(compare(toISOTimestamp(testTimestamp), '2005-02-03 22:01:03'), 0, "toISOTimestamp eq");
|
||||
testTimestamp = isoTimestamp('2005-2-3T22:01:03Z');
|
||||
t.is(toISOTimestamp(testTimestamp, true), '2005-02-03T22:01:03Z', "toISOTimestamp (real ISO) eq");
|
||||
|
||||
var localTZ = Math.round((new Date(2005,1,3,22,1,3)).getTimezoneOffset()/60)
|
||||
var direction = (localTZ < 0) ? "+" : "-";
|
||||
localTZ = Math.abs(localTZ);
|
||||
localTZ = direction + ((localTZ < 10) ? "0" : "") + localTZ;
|
||||
testTimestamp = isoTimestamp("2005-2-3T22:01:03" + localTZ);
|
||||
var testDateTimestamp = new Date(2005,1,3,22,1,3);
|
||||
t.is(compare(testTimestamp, testDateTimestamp), 0, "equal with local tz");
|
||||
testTimestamp = isoTimestamp("2005-2-3T17:01:03-05");
|
||||
var testDateTimestamp = new Date(Date.UTC(2005,1,3,22,1,3));
|
||||
t.is(compare(testTimestamp, testDateTimestamp), 0, "equal with specific tz");
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Signal'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Signal'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_DragAndDrop = function (t) {
|
||||
|
||||
var drag1 = new MochiKit.DragAndDrop.Draggable('drag1', {'revert': true, 'ghosting': true});
|
||||
|
||||
var drop1 = new MochiKit.DragAndDrop.Droppable('drop1', {'hoverclass': 'drop-hover'});
|
||||
drop1.activate();
|
||||
t.is(hasElementClass('drop1', 'drop-hover'), true, "hoverclass ok");
|
||||
drop1.deactivate();
|
||||
t.is(hasElementClass('drop1', 'drop-hover'), false, "remove hoverclass ok");
|
||||
drop1.destroy();
|
||||
|
||||
t.is( isEmpty(MochiKit.DragAndDrop.Droppables.drops), true, "Unregister droppable ok");
|
||||
|
||||
var onhover = function (element) {
|
||||
t.is(element, getElement('drag1'), 'onhover ok');
|
||||
};
|
||||
var drop2 = new MochiKit.DragAndDrop.Droppable('drop1', {'onhover': onhover});
|
||||
var pos = getElementPosition('drop1');
|
||||
pos = {"x": pos.x + 5, "y": pos.y + 5};
|
||||
MochiKit.DragAndDrop.Droppables.show({"page": pos}, getElement('drag1'));
|
||||
|
||||
drag1.destroy();
|
||||
t.is( isEmpty(MochiKit.DragAndDrop.Draggables.drops), true, "Unregister draggable ok");
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Format'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Format'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_Format = function (t) {
|
||||
t.is( truncToFixed(0.1234, 3), "0.123", "truncToFixed truncate" );
|
||||
t.is( truncToFixed(0.12, 3), "0.120", "truncToFixed trailing zeros" );
|
||||
t.is( truncToFixed(0.15, 1), "0.1", "truncToFixed no round" );
|
||||
t.is( truncToFixed(0.15, 0), "0", "truncToFixed zero (edge case)" );
|
||||
|
||||
t.is( roundToFixed(0.1234, 3), "0.123", "roundToFixed truncate" );
|
||||
t.is( roundToFixed(0.12, 3), "0.120", "roundToFixed trailing zeros" );
|
||||
t.is( roundToFixed(0.15, 1), "0.2", "roundToFixed round" );
|
||||
t.is( roundToFixed(0.15, 0), "0", "roundToFixed zero (edge case)" );
|
||||
|
||||
t.is( twoDigitFloat(-0.1234), "-0.12", "twoDigitFloat -0.1234 correct");
|
||||
t.is( twoDigitFloat(-0.1), "-0.1", "twoDigitFloat -0.1 correct");
|
||||
t.is( twoDigitFloat(-0), "0", "twoDigitFloat -0 correct");
|
||||
t.is( twoDigitFloat(0), "0", "twoDigitFloat 0 correct");
|
||||
t.is( twoDigitFloat(1), "1", "twoDigitFloat 1 correct");
|
||||
t.is( twoDigitFloat(1.0), "1", "twoDigitFloat 1.0 correct");
|
||||
t.is( twoDigitFloat(1.2), "1.2", "twoDigitFloat 1.2 correct");
|
||||
t.is( twoDigitFloat(1.234), "1.23", "twoDigitFloat 1.234 correct");
|
||||
t.is( percentFormat(123), "12300%", "percentFormat 123 correct");
|
||||
t.is( percentFormat(1.23), "123%", "percentFormat 123 correct");
|
||||
t.is( twoDigitAverage(1, 0), "0", "twoDigitAverage dbz correct");
|
||||
t.is( twoDigitAverage(1, 1), "1", "twoDigitAverage 1 correct");
|
||||
t.is( twoDigitAverage(1, 10), "0.1", "twoDigitAverage .1 correct");
|
||||
function reprIs(a, b) {
|
||||
arguments[0] = repr(a);
|
||||
arguments[1] = repr(b);
|
||||
t.is.apply(this, arguments);
|
||||
}
|
||||
reprIs( lstrip("\r\t\n foo \n\t\r"), "foo \n\t\r", "lstrip whitespace chars" );
|
||||
reprIs( rstrip("\r\t\n foo \n\t\r"), "\r\t\n foo", "rstrip whitespace chars" );
|
||||
reprIs( strip("\r\t\n foo \n\t\r"), "foo", "strip whitespace chars" );
|
||||
reprIs( lstrip("\r\n\t \r", "\r"), "\n\t \r", "lstrip custom chars" );
|
||||
reprIs( rstrip("\r\n\t \r", "\r"), "\r\n\t ", "rstrip custom chars" );
|
||||
reprIs( strip("\r\n\t \r", "\r"), "\n\t ", "strip custom chars" );
|
||||
|
||||
var nf = numberFormatter("$###,###.00 footer");
|
||||
t.is( nf(1000.1), "$1,000.10 footer", "trailing zeros" );
|
||||
t.is( nf(1000000.1), "$1,000,000.10 footer", "two seps" );
|
||||
t.is( nf(100), "$100.00 footer", "shorter than sep" );
|
||||
t.is( nf(100.555), "$100.56 footer", "rounding" );
|
||||
t.is( nf(-100.555), "$-100.56 footer", "default neg" );
|
||||
nf = numberFormatter("-$###,###.00");
|
||||
t.is( nf(-100.555), "-$100.56", "custom neg" );
|
||||
nf = numberFormatter("0000.0000");
|
||||
t.is( nf(0), "0000.0000", "leading and trailing" );
|
||||
t.is( nf(1.1), "0001.1000", "leading and trailing" );
|
||||
t.is( nf(12345.12345), "12345.1235", "no need for leading/trailing" );
|
||||
nf = numberFormatter("0000.0000");
|
||||
t.is( nf("taco"), "", "default placeholder" );
|
||||
nf = numberFormatter("###,###.00", "foo", "de_DE");
|
||||
t.is( nf("taco"), "foo", "custom placeholder" );
|
||||
t.is( nf(12345.12345), "12.345,12", "de_DE locale" );
|
||||
nf = numberFormatter("#%");
|
||||
t.is( nf(1), "100%", "trivial percent" );
|
||||
t.is( nf(0.55), "55%", "percent" );
|
||||
|
||||
var customLocale = {
|
||||
separator: " apples and ",
|
||||
decimal: " bagels at ",
|
||||
percent: "am for breakfast"};
|
||||
var customFormatter = numberFormatter("###,###.0%", "No breakfast", customLocale);
|
||||
t.is( customFormatter(23.458), "2 apples and 345 bagels at 8am for breakfast", "custom locale" );
|
||||
|
||||
nf = numberFormatter("###,###");
|
||||
t.is( nf(123), "123", "large number format" );
|
||||
t.is( nf(1234), "1,234", "large number format" );
|
||||
t.is( nf(12345), "12,345", "large number format" );
|
||||
t.is( nf(123456), "123,456", "large number format" );
|
||||
t.is( nf(1234567), "1,234,567", "large number format" );
|
||||
t.is( nf(12345678), "12,345,678", "large number format" );
|
||||
t.is( nf(123456789), "123,456,789", "large number format" );
|
||||
t.is( nf(1234567890), "1,234,567,890", "large number format" );
|
||||
t.is( nf(12345678901), "12,345,678,901", "large number format" );
|
||||
t.is( nf(123456789012), "123,456,789,012", "large number format" );
|
||||
};
|
|
@ -0,0 +1,176 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Iter'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Iter'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_Iter = function (t) {
|
||||
t.is( sum([1, 2, 3, 4, 5]), 15, "sum works on Arrays" );
|
||||
t.is( compare(list([1, 2, 3]), [1, 2, 3]), 0, "list([x]) == [x]" );
|
||||
t.is( compare(list(range(6, 0, -1)), [6, 5, 4, 3, 2, 1]), 0, "list(range(6, 0, -1)");
|
||||
t.is( compare(list(range(6)), [0, 1, 2, 3, 4, 5]), 0, "list(range(6))" );
|
||||
var moreThanTwo = partial(operator.lt, 2);
|
||||
t.is( sum(ifilter(moreThanTwo, range(6))), 12, "sum(ifilter(, range()))" );
|
||||
t.is( sum(ifilterfalse(moreThanTwo, range(6))), 3, "sum(ifilterfalse(, range()))" );
|
||||
|
||||
var c = count(10);
|
||||
t.is( compare([c.next(), c.next(), c.next()], [10, 11, 12]), 0, "count()" );
|
||||
c = cycle([1, 2]);
|
||||
t.is( compare([c.next(), c.next(), c.next()], [1, 2, 1]), 0, "cycle()" );
|
||||
c = repeat("foo", 3);
|
||||
t.is( compare(list(c), ["foo", "foo", "foo"]), 0, "repeat()" );
|
||||
c = izip([1, 2], [3, 4, 5], repeat("foo"));
|
||||
t.is( compare(list(c), [[1, 3, "foo"], [2, 4, "foo"]]), 0, "izip()" );
|
||||
|
||||
t.is( compare(list(range(5)), [0, 1, 2, 3, 4]), 0, "range(x)" );
|
||||
c = islice(range(10), 0, 10, 2);
|
||||
t.is( compare(list(c), [0, 2, 4, 6, 8]), 0, "islice(x, y, z)" );
|
||||
|
||||
c = imap(operator.add, [1, 2, 3], [2, 4, 6]);
|
||||
t.is( compare(list(c), [3, 6, 9]), 0, "imap(fn, p, q)" );
|
||||
|
||||
c = filter(partial(operator.lt, 1), iter([1, 2, 3]));
|
||||
t.is( compare(c, [2, 3]), 0, "filter(fn, iterable)" );
|
||||
|
||||
c = map(partial(operator.add, -1), iter([1, 2, 3]));
|
||||
t.is( compare(c, [0, 1, 2]), 0, "map(fn, iterable)" );
|
||||
|
||||
c = map(operator.add, iter([1, 2, 3]), [2, 4, 6]);
|
||||
t.is( compare(c, [3, 6, 9]), 0, "map(fn, iterable, q)" );
|
||||
|
||||
c = map(operator.add, iter([1, 2, 3]), iter([2, 4, 6]));
|
||||
t.is( compare(c, [3, 6, 9]), 0, "map(fn, iterable, iterable)" );
|
||||
|
||||
c = applymap(operator.add, [[1, 2], [2, 4], [3, 6]]);
|
||||
t.is( compare(list(c), [3, 6, 9]), 0, "applymap()" );
|
||||
|
||||
c = applymap(function (a) { return [this, a]; }, [[1], [2]], 1);
|
||||
t.is( compare(list(c), [[1, 1], [1, 2]]), 0, "applymap(self)" );
|
||||
|
||||
c = chain(range(2), range(3));
|
||||
t.is( compare(list(c), [0, 1, 0, 1, 2]), 0, "chain(p, q)" );
|
||||
|
||||
var lessThanFive = partial(operator.gt, 5);
|
||||
c = takewhile(lessThanFive, count());
|
||||
t.is( compare(list(c), [0, 1, 2, 3, 4]), 0, "takewhile()" );
|
||||
|
||||
c = dropwhile(lessThanFive, range(10));
|
||||
t.is( compare(list(c), [5, 6, 7, 8, 9]), 0, "dropwhile()" );
|
||||
|
||||
c = tee(range(5), 3);
|
||||
t.is( compare(list(c[0]), list(c[1])), 0, "tee(..., 3) p0 == p1" );
|
||||
t.is( compare(list(c[2]), [0, 1, 2, 3, 4]), 0, "tee(..., 3) p2 == fixed" );
|
||||
|
||||
t.is( compare(reduce(operator.add, range(10)), 45), 0, "reduce(op.add)" );
|
||||
|
||||
try {
|
||||
reduce(operator.add, []);
|
||||
t.ok( false, "reduce didn't raise anything with empty list and no start?!" );
|
||||
} catch (e) {
|
||||
if (e instanceof TypeError) {
|
||||
t.ok( true, "reduce raised TypeError correctly" );
|
||||
} else {
|
||||
t.ok( false, "reduce raised the wrong exception?" );
|
||||
}
|
||||
}
|
||||
|
||||
t.is( reduce(operator.add, [], 10), 10, "range initial value OK empty" );
|
||||
t.is( reduce(operator.add, [1], 10), 11, "range initial value OK populated" );
|
||||
|
||||
t.is( compare(iextend([1], range(2)), [1, 0, 1]), 0, "iextend(...)" );
|
||||
|
||||
var x = [];
|
||||
exhaust(imap(bind(x.push, x), range(5)));
|
||||
t.is( compare(x, [0, 1, 2, 3, 4]), 0, "exhaust(...)" );
|
||||
|
||||
t.is( every([1, 2, 3, 4, 5, 4], lessThanFive), false, "every false" );
|
||||
t.is( every([1, 2, 3, 4, 4], lessThanFive), true, "every true" );
|
||||
t.is( some([1, 2, 3, 4, 4], lessThanFive), true, "some true" );
|
||||
t.is( some([5, 6, 7, 8, 9], lessThanFive), false, "some false" );
|
||||
t.is( some([5, 6, 7, 8, 4], lessThanFive), true, "some true" );
|
||||
|
||||
var rval = [];
|
||||
forEach(range(2), rval.push, rval);
|
||||
t.is( compare(rval, [0, 1]), 0, "forEach works bound" );
|
||||
|
||||
function foo(o) {
|
||||
rval.push(o);
|
||||
}
|
||||
forEach(range(2), foo);
|
||||
t.is( compare(rval, [0, 1, 0, 1]), 0, "forEach works unbound" );
|
||||
|
||||
t.is( compare(sorted([3, 2, 1]), [1, 2, 3]), 0, "sorted default" );
|
||||
rval = sorted(["aaa", "bb", "c"], keyComparator("length"));
|
||||
t.is(compare(rval, ["c", "bb", "aaa"]), 0, "sorted custom");
|
||||
|
||||
t.is( compare(reversed(range(4)), [3, 2, 1, 0]), 0, "reversed iterator" );
|
||||
t.is( compare(reversed([5, 6, 7]), [7, 6, 5]), 0, "reversed list" );
|
||||
|
||||
var o = {lst: [1, 2, 3], iterateNext: function () { return this.lst.shift(); }};
|
||||
t.is( compare(list(o), [1, 2, 3]), 0, "iterateNext" );
|
||||
|
||||
|
||||
function except(exc, func) {
|
||||
try {
|
||||
func();
|
||||
t.ok(false, exc.name + " was not raised.");
|
||||
} catch (e) {
|
||||
if (e == exc) {
|
||||
t.ok( true, "raised " + exc.name + " correctly" );
|
||||
} else {
|
||||
t.ok( false, "raised the wrong exception?" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
odd = partial(operator.and, 1)
|
||||
|
||||
// empty
|
||||
grouped = groupby([]);
|
||||
except(StopIteration, grouped.next);
|
||||
|
||||
// exhaust sub-iterator
|
||||
grouped = groupby([2,4,6,7], odd);
|
||||
kv = grouped.next(); k = kv[0], subiter = kv[1];
|
||||
t.is(k, 0, "odd(2) = odd(4) = odd(6) == 0");
|
||||
t.is(subiter.next(), 2, "sub-iterator.next() == 2");
|
||||
t.is(subiter.next(), 4, "sub-iterator.next() == 4");
|
||||
t.is(subiter.next(), 6, "sub-iterator.next() == 6");
|
||||
except(StopIteration, subiter.next);
|
||||
kv = grouped.next(); key = kv[0], subiter = kv[1];
|
||||
t.is(key, 1, "odd(7) == 1");
|
||||
t.is(subiter.next(), 7, "sub-iterator.next() == 7");
|
||||
except(StopIteration, subiter.next);
|
||||
|
||||
// not consume sub-iterator
|
||||
grouped = groupby([2,4,6,7], odd);
|
||||
kv = grouped.next(); key = kv[0], subiter = kv[1];
|
||||
t.is(key, 0, "0 = odd(2) = odd(4) = odd(6)");
|
||||
kv = grouped.next(); key = kv[0], subiter = kv[1];
|
||||
t.is(key, 1, "1 = odd(7)");
|
||||
except(StopIteration, grouped.next);
|
||||
|
||||
// consume sub-iterator partially
|
||||
grouped = groupby([3,1,1,2], odd);
|
||||
kv = grouped.next(); key = kv[0], subiter = kv[1];
|
||||
t.is(key, 1, "odd(1) == 1");
|
||||
t.is(subiter.next(), 3, "sub-iterator.next() == 3");
|
||||
kv = grouped.next(); key = kv[0], v = kv[1];
|
||||
t.is(key, 0, "skip (1,1), odd(2) == 0");
|
||||
except(StopIteration, grouped.next);
|
||||
|
||||
// null
|
||||
grouped = groupby([null,null]);
|
||||
kv = grouped.next(); k = kv[0], v = kv[1];
|
||||
t.is(k, null, "null ok");
|
||||
|
||||
// groupby - array version
|
||||
isEqual = (t.isDeeply || function (a, b, msg) {
|
||||
return t.ok(compare(a, b) == 0, msg);
|
||||
});
|
||||
isEqual(groupby_as_array([ ] ), [ ], "empty");
|
||||
isEqual(groupby_as_array([1,1,1]), [ [1,[1,1,1]] ], "[1,1,1]: [1,1,1]");
|
||||
isEqual(groupby_as_array([1,2,2]), [ [1,[1] ], [2,[2,2]] ], "[1,2,2]: [1], [2,2]");
|
||||
isEqual(groupby_as_array([1,1,2]), [ [1,[1,1] ], [2,[2 ]] ], "[1,1,2]: [1,1], [2]");
|
||||
isEqual(groupby_as_array([null,null] ), [ [null,[null,null]] ], "[null,null]: [null,null]");
|
||||
grouped = groupby_as_array([1,1,3,2,4,6,8], odd);
|
||||
isEqual(grouped, [[1, [1,1,3]], [0,[2,4,6,8]]], "[1,1,3,2,4,6,7] odd: [1,1,3], [2,4,6,8]");
|
||||
};
|
|
@ -0,0 +1,75 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Logging'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Logging'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_Logging = function (t) {
|
||||
|
||||
// just in case
|
||||
logger.clear();
|
||||
|
||||
t.is( logLevelAtLeast('DEBUG')('INFO'), false, 'logLevelAtLeast false' );
|
||||
t.is( logLevelAtLeast('WARNING')('INFO'), false, 'logLevelAtLeast true' );
|
||||
t.ok( logger instanceof Logger, "global logger installed" );
|
||||
|
||||
var allMessages = [];
|
||||
logger.addListener("allMessages", null,
|
||||
bind(allMessages.push, allMessages));
|
||||
|
||||
var fatalMessages = [];
|
||||
logger.addListener("fatalMessages", "FATAL",
|
||||
bind(fatalMessages.push, fatalMessages));
|
||||
|
||||
var firstTwo = [];
|
||||
logger.addListener("firstTwo", null,
|
||||
bind(firstTwo.push, firstTwo));
|
||||
|
||||
|
||||
log("foo");
|
||||
var msgs = logger.getMessages();
|
||||
t.is( msgs.length, 1, 'global log() put one message in queue' );
|
||||
t.is( compare(allMessages, msgs), 0, "allMessages listener" );
|
||||
var msg = msgs.pop();
|
||||
t.is( compare(msg.info, ["foo"]), 0, "info matches" );
|
||||
t.is( msg.level, "INFO", "level matches" );
|
||||
|
||||
logDebug("debugFoo");
|
||||
t.is( msgs.length, 0, 'getMessages() returns copy' );
|
||||
msgs = logger.getMessages();
|
||||
t.is( compare(allMessages, msgs), 0, "allMessages listener" );
|
||||
t.is( msgs.length, 2, 'logDebug()' );
|
||||
msg = msgs.pop();
|
||||
t.is( compare(msg.info, ["debugFoo"]), 0, "info matches" );
|
||||
t.is( msg.level, "DEBUG", "level matches" );
|
||||
|
||||
logger.removeListener("firstTwo");
|
||||
|
||||
logError("errorFoo");
|
||||
msgs = logger.getMessages();
|
||||
t.is( compare(allMessages, msgs), 0, "allMessages listener" );
|
||||
t.is( msgs.length, 3, 'logError()' );
|
||||
msg = msgs.pop();
|
||||
t.is( compare(msg.info, ["errorFoo"]), 0, "info matches" );
|
||||
t.is( msg.level, "ERROR", "level matches" );
|
||||
|
||||
logWarning("warningFoo");
|
||||
msgs = logger.getMessages();
|
||||
t.is( compare(allMessages, msgs), 0, "allMessages listener" );
|
||||
t.is( msgs.length, 4, 'logWarning()' );
|
||||
msg = msgs.pop();
|
||||
t.is( compare(msg.info, ["warningFoo"]), 0, "info matches" );
|
||||
t.is( msg.level, "WARNING", "level matches" );
|
||||
|
||||
logFatal("fatalFoo");
|
||||
msgs = logger.getMessages();
|
||||
t.is( compare(allMessages, msgs), 0, "allMessages listener" );
|
||||
t.is( msgs.length, 5, 'logFatal()' );
|
||||
msg = msgs.pop();
|
||||
t.is( compare(fatalMessages, [msg]), 0, "fatalMessages listener" );
|
||||
t.is( compare(msg.info, ["fatalFoo"]), 0, "info matches" );
|
||||
t.is( msg.level, "FATAL", "level matches" );
|
||||
|
||||
logger.removeListener("allMessages");
|
||||
logger.removeListener("fatalMessages");
|
||||
|
||||
t.is( compare(firstTwo, logger.getMessages().slice(0, 2)), 0, "firstTwo" );
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
{"passed": true}
|
|
@ -0,0 +1,441 @@
|
|||
if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Signal'); }
|
||||
if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Signal'); }
|
||||
if (typeof(tests) == 'undefined') { tests = {}; }
|
||||
|
||||
tests.test_Signal = function (t) {
|
||||
|
||||
var submit = MochiKit.DOM.getElement('submit');
|
||||
var ident = null;
|
||||
var i = 0;
|
||||
var aFunction = function() {
|
||||
t.ok(this === submit, "aFunction should have 'this' as submit");
|
||||
i++;
|
||||
if (typeof(this.someVar) != 'undefined') {
|
||||
i += this.someVar;
|
||||
}
|
||||
};
|
||||
|
||||
var aObject = {};
|
||||
aObject.aMethod = function() {
|
||||
t.ok(this === aObject, "aMethod should have 'this' as aObject");
|
||||
i++;
|
||||
};
|
||||
|
||||
ident = connect('submit', 'onclick', aFunction);
|
||||
MochiKit.DOM.getElement('submit').click();
|
||||
t.is(i, 1, 'HTML onclick event can be connected to a function');
|
||||
|
||||
disconnect(ident);
|
||||
MochiKit.DOM.getElement('submit').click();
|
||||
t.is(i, 1, 'HTML onclick can be disconnected from a function');
|
||||
|
||||
var submit = MochiKit.DOM.getElement('submit');
|
||||
|
||||
ident = connect(submit, 'onclick', aFunction);
|
||||
submit.click();
|
||||
t.is(i, 2, 'Checking that a DOM element can be connected to a function');
|
||||
|
||||
disconnect(ident);
|
||||
submit.click();
|
||||
t.is(i, 2, '...and then disconnected');
|
||||
|
||||
if (MochiKit.DOM.getElement('submit').fireEvent ||
|
||||
(document.createEvent &&
|
||||
typeof(document.createEvent('MouseEvents').initMouseEvent) == 'function')) {
|
||||
|
||||
/*
|
||||
|
||||
Adapted from:
|
||||
http://www.devdaily.com/java/jwarehouse/jforum/tests/selenium/javascript/htmlutils.js.shtml
|
||||
License: Apache
|
||||
Copyright: Copyright 2004 ThoughtWorks, Inc
|
||||
|
||||
*/
|
||||
var triggerMouseEvent = function(element, eventType, canBubble) {
|
||||
element = MochiKit.DOM.getElement(element);
|
||||
canBubble = (typeof(canBubble) == 'undefined') ? true : canBubble;
|
||||
if (element.fireEvent) {
|
||||
var newEvt = document.createEventObject();
|
||||
newEvt.clientX = 1;
|
||||
newEvt.clientY = 1;
|
||||
newEvt.button = 1;
|
||||
element.fireEvent('on' + eventType, newEvt);
|
||||
} else if (document.createEvent && (typeof(document.createEvent('MouseEvents').initMouseEvent) == 'function')) {
|
||||
var evt = document.createEvent('MouseEvents');
|
||||
evt.initMouseEvent(eventType, canBubble, true, // event, bubbles, cancelable
|
||||
document.defaultView, 1, // view, # of clicks
|
||||
1, 0, 0, 0, // screenX, screenY, clientX, clientY
|
||||
false, false, false, false, // ctrlKey, altKey, shiftKey, metaKey
|
||||
0, null); // buttonCode, relatedTarget
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
};
|
||||
|
||||
var eventTest = function(e) {
|
||||
i++;
|
||||
t.ok((typeof(e.event()) === 'object'), 'checking that event() is an object');
|
||||
t.ok((typeof(e.type()) === 'string'), 'checking that type() is a string');
|
||||
t.ok((e.target() === MochiKit.DOM.getElement('submit')), 'checking that target is "submit"');
|
||||
t.ok((typeof(e.modifier()) === 'object'), 'checking that modifier() is an object');
|
||||
t.ok(e.modifier().alt === false, 'checking that modifier().alt is defined, but false');
|
||||
t.ok(e.modifier().ctrl === false, 'checking that modifier().ctrl is defined, but false');
|
||||
t.ok(e.modifier().meta === false, 'checking that modifier().meta is defined, but false');
|
||||
t.ok(e.modifier().shift === false, 'checking that modifier().shift is defined, but false');
|
||||
t.ok((typeof(e.mouse()) === 'object'), 'checking that mouse() is an object');
|
||||
t.ok((typeof(e.mouse().button) === 'object'), 'checking that mouse().button is an object');
|
||||
t.ok(e.mouse().button.left === true, 'checking that mouse().button.left is true');
|
||||
t.ok(e.mouse().button.middle === false, 'checking that mouse().button.middle is false');
|
||||
t.ok(e.mouse().button.right === false, 'checking that mouse().button.right is false');
|
||||
t.ok((typeof(e.mouse().page) === 'object'), 'checking that mouse().page is an object');
|
||||
t.ok((typeof(e.mouse().page.x) === 'number'), 'checking that mouse().page.x is a number');
|
||||
t.ok((typeof(e.mouse().page.y) === 'number'), 'checking that mouse().page.y is a number');
|
||||
t.ok((typeof(e.mouse().client) === 'object'), 'checking that mouse().client is an object');
|
||||
t.ok((typeof(e.mouse().client.x) === 'number'), 'checking that mouse().client.x is a number');
|
||||
t.ok((typeof(e.mouse().client.y) === 'number'), 'checking that mouse().client.y is a number');
|
||||
|
||||
/* these should not be defined */
|
||||
t.ok((typeof(e.relatedTarget()) === 'undefined'), 'checking that relatedTarget() is undefined');
|
||||
t.ok((typeof(e.key()) === 'undefined'), 'checking that key() is undefined');
|
||||
};
|
||||
|
||||
|
||||
ident = connect('submit', 'onmousedown', eventTest);
|
||||
triggerMouseEvent('submit', 'mousedown', false);
|
||||
t.is(i, 3, 'Connecting an event to an HTML object and firing a synthetic event');
|
||||
|
||||
disconnect(ident);
|
||||
triggerMouseEvent('submit', 'mousedown', false);
|
||||
t.is(i, 3, 'Disconnecting an event to an HTML object and firing a synthetic event');
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// non-DOM tests
|
||||
|
||||
var hasNoSignals = {};
|
||||
|
||||
var hasSignals = {someVar: 1};
|
||||
|
||||
var i = 0;
|
||||
|
||||
var aFunction = function() {
|
||||
i++;
|
||||
if (typeof(this.someVar) != 'undefined') {
|
||||
i += this.someVar;
|
||||
}
|
||||
};
|
||||
|
||||
var bFunction = function(someArg, someOtherArg) {
|
||||
i += someArg + someOtherArg;
|
||||
};
|
||||
|
||||
|
||||
var aObject = {};
|
||||
aObject.aMethod = function() {
|
||||
i++;
|
||||
};
|
||||
|
||||
aObject.bMethod = function() {
|
||||
i++;
|
||||
};
|
||||
|
||||
var bObject = {};
|
||||
bObject.bMethod = function() {
|
||||
i++;
|
||||
};
|
||||
|
||||
|
||||
ident = connect(hasSignals, 'signalOne', aFunction);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 2, 'Connecting function');
|
||||
i = 0;
|
||||
|
||||
disconnect(ident);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'New style disconnecting function');
|
||||
i = 0;
|
||||
|
||||
|
||||
ident = connect(hasSignals, 'signalOne', bFunction);
|
||||
signal(hasSignals, 'signalOne', 1, 2);
|
||||
t.is(i, 3, 'Connecting function');
|
||||
i = 0;
|
||||
|
||||
disconnect(ident);
|
||||
signal(hasSignals, 'signalOne', 1, 2);
|
||||
t.is(i, 0, 'New style disconnecting function');
|
||||
i = 0;
|
||||
|
||||
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 2, 'Connecting function');
|
||||
i = 0;
|
||||
|
||||
disconnect(hasSignals, 'signalOne', aFunction);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'Old style disconnecting function');
|
||||
i = 0;
|
||||
|
||||
|
||||
ident = connect(hasSignals, 'signalOne', aObject, aObject.aMethod);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 1, 'Connecting obj-function');
|
||||
i = 0;
|
||||
|
||||
disconnect(ident);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'New style disconnecting obj-function');
|
||||
i = 0;
|
||||
|
||||
connect(hasSignals, 'signalOne', aObject, aObject.aMethod);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 1, 'Connecting obj-function');
|
||||
i = 0;
|
||||
|
||||
disconnect(hasSignals, 'signalOne', aObject, aObject.aMethod);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'Disconnecting obj-function');
|
||||
i = 0;
|
||||
|
||||
|
||||
ident = connect(hasSignals, 'signalTwo', aObject, 'aMethod');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 1, 'Connecting obj-string');
|
||||
i = 0;
|
||||
|
||||
disconnect(ident);
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 0, 'New style disconnecting obj-string');
|
||||
i = 0;
|
||||
|
||||
|
||||
connect(hasSignals, 'signalTwo', aObject, 'aMethod');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 1, 'Connecting obj-string');
|
||||
i = 0;
|
||||
|
||||
disconnect(hasSignals, 'signalTwo', aObject, 'aMethod');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 0, 'Old style disconnecting obj-string');
|
||||
i = 0;
|
||||
|
||||
|
||||
var shouldRaise = function() { return undefined.attr; };
|
||||
|
||||
try {
|
||||
connect(hasSignals, 'signalOne', shouldRaise);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.ok(false, 'An exception was not raised');
|
||||
} catch (e) {
|
||||
t.ok(true, 'An exception was raised');
|
||||
}
|
||||
disconnect(hasSignals, 'signalOne', shouldRaise);
|
||||
t.is(i, 0, 'Exception raised, signal should not have fired');
|
||||
i = 0;
|
||||
|
||||
|
||||
connect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
connect(hasSignals, 'signalOne', aObject, 'bMethod');
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 2, 'Connecting one signal to two slots in one object');
|
||||
i = 0;
|
||||
|
||||
disconnect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
disconnect(hasSignals, 'signalOne', aObject, 'bMethod');
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'Disconnecting one signal from two slots in one object');
|
||||
i = 0;
|
||||
|
||||
|
||||
connect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
connect(hasSignals, 'signalOne', bObject, 'bMethod');
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 2, 'Connecting one signal to two slots in two objects');
|
||||
i = 0;
|
||||
|
||||
disconnect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
disconnect(hasSignals, 'signalOne', bObject, 'bMethod');
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'Disconnecting one signal from two slots in two objects');
|
||||
i = 0;
|
||||
|
||||
|
||||
try {
|
||||
connect(nothing, 'signalOne', aObject, 'aMethod');
|
||||
signal(nothing, 'signalOne');
|
||||
t.ok(false, 'An exception was not raised when connecting undefined');
|
||||
} catch (e) {
|
||||
t.ok(true, 'An exception was raised when connecting undefined');
|
||||
}
|
||||
|
||||
try {
|
||||
disconnect(nothing, 'signalOne', aObject, 'aMethod');
|
||||
t.ok(false, 'An exception was not raised when disconnecting undefined');
|
||||
} catch (e) {
|
||||
t.ok(true, 'An exception was raised when disconnecting undefined');
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
connect(hasSignals, 'signalOne', nothing);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.ok(false, 'An exception was not raised when connecting an undefined function');
|
||||
} catch (e) {
|
||||
t.ok(true, 'An exception was raised when connecting an undefined function');
|
||||
}
|
||||
|
||||
try {
|
||||
disconnect(hasSignals, 'signalOne', nothing);
|
||||
t.ok(false, 'An exception was not raised when disconnecting an undefined function');
|
||||
} catch (e) {
|
||||
t.ok(true, 'An exception was raised when disconnecting an undefined function');
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
connect(hasSignals, 'signalOne', aObject, aObject.nothing);
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.ok(false, 'An exception was not raised when connecting an undefined method');
|
||||
} catch (e) {
|
||||
t.ok(true, 'An exception was raised when connecting an undefined method');
|
||||
}
|
||||
|
||||
try {
|
||||
connect(hasSignals, 'signalOne', aObject, 'nothing');
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.ok(false, 'An exception was not raised when connecting an undefined method (as string)');
|
||||
} catch (e) {
|
||||
t.ok(true, 'An exception was raised when connecting an undefined method (as string)');
|
||||
}
|
||||
|
||||
t.is(i, 0, 'Signals should not have fired');
|
||||
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
connect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
disconnectAll(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'disconnectAll works with single explicit signal');
|
||||
i = 0;
|
||||
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
connect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
connect(hasSignals, 'signalTwo', aFunction);
|
||||
connect(hasSignals, 'signalTwo', aObject, 'aMethod');
|
||||
disconnectAll(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalOne');
|
||||
t.is(i, 0, 'disconnectAll works with single explicit signal');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 3, 'disconnectAll does not disconnect unrelated signals');
|
||||
i = 0;
|
||||
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
connect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
connect(hasSignals, 'signalTwo', aFunction);
|
||||
connect(hasSignals, 'signalTwo', aObject, 'aMethod');
|
||||
disconnectAll(hasSignals, 'signalOne', 'signalTwo');
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 0, 'disconnectAll works with two explicit signals');
|
||||
i = 0;
|
||||
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
connect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
connect(hasSignals, 'signalTwo', aFunction);
|
||||
connect(hasSignals, 'signalTwo', aObject, 'aMethod');
|
||||
disconnectAll(hasSignals, ['signalOne', 'signalTwo']);
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 0, 'disconnectAll works with two explicit signals as a list');
|
||||
i = 0;
|
||||
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
connect(hasSignals, 'signalOne', aObject, 'aMethod');
|
||||
connect(hasSignals, 'signalTwo', aFunction);
|
||||
connect(hasSignals, 'signalTwo', aObject, 'aMethod');
|
||||
disconnectAll(hasSignals);
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 0, 'disconnectAll works with implicit signals');
|
||||
i = 0;
|
||||
|
||||
var toggle = function() {
|
||||
disconnectAll(hasSignals, 'signalOne');
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
i++;
|
||||
};
|
||||
|
||||
connect(hasSignals, 'signalOne', aFunction);
|
||||
connect(hasSignals, 'signalTwo', function() { i++; });
|
||||
connect(hasSignals, 'signalTwo', toggle);
|
||||
connect(hasSignals, 'signalTwo', function() { i++; }); // #147
|
||||
connect(hasSignals, 'signalTwo', function() { i++; });
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(i, 4, 'disconnectAll fired in a signal loop works');
|
||||
i = 0;
|
||||
disconnectAll('signalOne');
|
||||
disconnectAll('signalTwo');
|
||||
|
||||
var testfunc = function () { arguments.callee.count++; };
|
||||
testfunc.count = 0;
|
||||
var testObj = {
|
||||
methOne: function () { this.countOne++; }, countOne: 0,
|
||||
methTwo: function () { this.countTwo++; }, countTwo: 0
|
||||
};
|
||||
connect(hasSignals, 'signalOne', testfunc);
|
||||
connect(hasSignals, 'signalTwo', testfunc);
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(testfunc.count, 2, 'disconnectAllTo func precondition');
|
||||
disconnectAllTo(testfunc);
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(testfunc.count, 2, 'disconnectAllTo func');
|
||||
|
||||
connect(hasSignals, 'signalOne', testObj, 'methOne');
|
||||
connect(hasSignals, 'signalTwo', testObj, 'methTwo');
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(testObj.countOne, 1, 'disconnectAllTo obj precondition');
|
||||
t.is(testObj.countTwo, 1, 'disconnectAllTo obj precondition');
|
||||
disconnectAllTo(testObj);
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(testObj.countOne, 1, 'disconnectAllTo obj');
|
||||
t.is(testObj.countTwo, 1, 'disconnectAllTo obj');
|
||||
|
||||
testObj.countOne = testObj.countTwo = 0;
|
||||
connect(hasSignals, 'signalOne', testObj, 'methOne');
|
||||
connect(hasSignals, 'signalTwo', testObj, 'methTwo');
|
||||
disconnectAllTo(testObj, 'methOne');
|
||||
signal(hasSignals, 'signalOne');
|
||||
signal(hasSignals, 'signalTwo');
|
||||
t.is(testObj.countOne, 0, 'disconnectAllTo obj+str');
|
||||
t.is(testObj.countTwo, 1, 'disconnectAllTo obj+str');
|
||||
|
||||
has__Connect = {
|
||||
count: 0,
|
||||
__connect__: function (ident) {
|
||||
this.count += arguments.length;
|
||||
disconnect(ident);
|
||||
}
|
||||
};
|
||||
|
||||
connect(has__Connect, 'signalOne', aFunction);
|
||||
t.is(has__Connect.count, 3, '__connect__ is called when it exists');
|
||||
signal(has__Connect, 'signalOne');
|
||||
t.is(has__Connect.count, 3, '__connect__ can disconnect the signal');
|
||||
|
||||
var events = {};
|
||||
var test_ident = connect(events, "test", function() {
|
||||
var fail_ident = connect(events, "fail", function () {
|
||||
events.failed = true;
|
||||
});
|
||||
disconnect(fail_ident);
|
||||
signal(events, "fail");
|
||||
});
|
||||
signal(events, "test");
|
||||
t.is(events.failed, undefined, 'disconnected slots do not fire');
|
||||
|
||||
};
|
Загрузка…
Ссылка в новой задаче