Merged 3.1 to HEAD

13275: updated web-client to use tinymce v3
 13276: overlay display fix for when field has large content


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13585 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Lawrence Carvalho
2009-03-12 10:00:20 +00:00
parent f6b762476a
commit d5fbd06a47
380 changed files with 55391 additions and 11133 deletions

View File

@@ -0,0 +1,126 @@
/**
* $Id: Cookie.js 520 2008-01-07 16:30:32Z spocke $
*
* @author Moxiecode
* @copyright Copyright <20> 2004-2008, Moxiecode Systems AB, All rights reserved.
*/
(function() {
var each = tinymce.each;
/**#@+
* @class This class contains simple cookie manangement functions.
* @member tinymce.util.Cookie
* @static
*/
tinymce.create('static tinymce.util.Cookie', {
/**#@+
* @method
*/
/**
* Parses the specified query string into an name/value object.
*
* @param {String} n String to parse into a n Hashtable object.
* @return {Object} Name/Value object with items parsed from querystring.
*/
getHash : function(n) {
var v = this.get(n), h;
if (v) {
each(v.split('&'), function(v) {
v = v.split('=');
h = h || {};
h[unescape(v[0])] = unescape(v[1]);
});
}
return h;
},
/**
* Sets a hashtable name/value object to a cookie.
*
* @param {String} n Name of the cookie.
* @param {Object} v Hashtable object to set as cookie.
* @param {Date} d Optional date object for the expiration of the cookie.
* @param {String} p Optional path to restrict the cookie to.
* @param {String} d Optional domain to restrict the cookie to.
* @param {String} s Is the cookie secure or not.
*/
setHash : function(n, v, e, p, d, s) {
var o = '';
each(v, function(v, k) {
o += (!o ? '' : '&') + escape(k) + '=' + escape(v);
});
this.set(n, o, e, p, d, s);
},
/**
* Gets the raw data of a cookie by name.
*
* @param {String} n Name of cookie to retrive.
* @return {String} Cookie data string.
*/
get : function(n) {
var c = document.cookie, e, p = n + "=", b;
// Strict mode
if (!c)
return;
b = c.indexOf("; " + p);
if (b == -1) {
b = c.indexOf(p);
if (b != 0)
return null;
} else
b += 2;
e = c.indexOf(";", b);
if (e == -1)
e = c.length;
return unescape(c.substring(b + p.length, e));
},
/**
* Sets a raw cookie string.
*
* @param {String} n Name of the cookie.
* @param {String} v Raw cookie data.
* @param {Date} d Optional date object for the expiration of the cookie.
* @param {String} p Optional path to restrict the cookie to.
* @param {String} d Optional domain to restrict the cookie to.
* @param {String} s Is the cookie secure or not.
*/
set : function(n, v, e, p, d, s) {
document.cookie = n + "=" + escape(v) +
((e) ? "; expires=" + e.toGMTString() : "") +
((p) ? "; path=" + escape(p) : "") +
((d) ? "; domain=" + d : "") +
((s) ? "; secure" : "");
},
/**
* Removes/deletes a cookie by name.
*
* @param {String} n Cookie name to remove/delete.
* @param {Strong} p Optional path to remove the cookie from.
*/
remove : function(n, p) {
var d = new Date();
d.setTime(d.getTime() - 1000);
this.set(n, '', d, p, d);
}
/**#@-*/
});
})();

View File

@@ -0,0 +1,101 @@
/**
* $Id: Dispatcher.js 743 2008-03-23 17:47:33Z spocke $
*
* @author Moxiecode
* @copyright Copyright <20> 2004-2006, Moxiecode Systems AB, All rights reserved.
*/
/**#@+
* @class This class is used to dispatch event to observers/listeners.
* All internal events inside TinyMCE uses this class.
* @member tinymce.util.Dispatcher
*/
tinymce.create('tinymce.util.Dispatcher', {
scope : null,
listeners : null,
/**
* Constructs a new event dispatcher object.
*
* @constructor
* @param {Object} s Optional default execution scope for all observer functions.
*/
Dispatcher : function(s) {
this.scope = s || this;
this.listeners = [];
},
/**#@+
* @method
*/
/**
* Add an observer function to be executed when a dispatch call is done.
*
* @param {function} cb Callback function to execute when a dispatch event occurs.
* @param {Object} s Optional execution scope, defaults to the one specified in the class constructor.
* @return {function} Returns the same function as the one passed on.
*/
add : function(cb, s) {
this.listeners.push({cb : cb, scope : s || this.scope});
return cb;
},
/**
* Add an observer function to be executed to the top of the list of observers.
*
* @param {function} cb Callback function to execute when a dispatch event occurs.
* @param {Object} s Optional execution scope, defaults to the one specified in the class constructor.
* @return {function} Returns the same function as the one passed on.
*/
addToTop : function(cb, s) {
this.listeners.unshift({cb : cb, scope : s || this.scope});
return cb;
},
/**
* Removes an observer function.
*
* @param {function} cb Observer function to remove.
* @return {function} The same function that got passed in or null if it wasn't found.
*/
remove : function(cb) {
var l = this.listeners, o = null;
tinymce.each(l, function(c, i) {
if (cb == c.cb) {
o = cb;
l.splice(i, 1);
return false;
}
});
return o;
},
/**
* Dispatches an event to all observers/listeners.
*
* @param {Object} .. Any number of arguments to dispatch.
* @return {Object} Last observer functions return value.
*/
dispatch : function() {
var s, a = arguments, i, li = this.listeners, c;
// Needs to be a real loop since the listener count might change while looping
// And this is also more efficient
for (i = 0; i<li.length; i++) {
c = li[i];
s = c.cb.apply(c.scope, a);
if (s === false)
break;
}
return s;
}
/**#@-*/
});

View File

@@ -0,0 +1,81 @@
/**
* $Id: JSON.js 920 2008-09-09 14:05:33Z spocke $
*
* @author Moxiecode
* @copyright Copyright <20> 2004-2006, Moxiecode Systems AB, All rights reserved.
*/
/**#@+
* @class JSON parser and serializer class.
* @member tinymce.util.JSON
* @static
*/
tinymce.create('static tinymce.util.JSON', {
/**#@+
* @method
*/
/**
* Serializes the specified object as a JSON string.
*
* @param {Object} o Object to serialize as a JSON string.
* @return {string} JSON string serialized from input.
*/
serialize : function(o) {
var i, v, s = tinymce.util.JSON.serialize, t;
if (o == null)
return 'null';
t = typeof o;
if (t == 'string') {
v = '\bb\tt\nn\ff\rr\""\'\'\\\\';
return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g, function(a, b) {
i = v.indexOf(b);
if (i + 1)
return '\\' + v.charAt(i + 1);
a = b.charCodeAt().toString(16);
return '\\u' + '0000'.substring(a.length) + a;
}) + '"';
}
if (t == 'object') {
if (o instanceof Array) {
for (i=0, v = '['; i<o.length; i++)
v += (i > 0 ? ',' : '') + s(o[i]);
return v + ']';
}
v = '{';
for (i in o)
v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';
return v + '}';
}
return '' + o;
},
/**
* Unserializes/parses the specified JSON string into a object.
*
* @param {string} s JSON String to parse into a JavaScript object.
* @return {Object} Object from input JSON string or undefined if it failed.
*/
parse : function(s) {
try {
return eval('(' + s + ')');
} catch (ex) {
// Ignore
}
}
/**#@-*/
});

View File

@@ -0,0 +1,87 @@
/**
* $Id: JSONRequest.js 578 2008-01-31 11:05:10Z spocke $
*
* @author Moxiecode
* @copyright Copyright <20> 2004-2006, Moxiecode Systems AB, All rights reserved.
*/
(function() {
var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;
/**#@+
* @class This class enables you to use JSON-RPC to call backend methods.
* @member tinymce.util.JSONRequest
*/
tinymce.create('tinymce.util.JSONRequest', {
/**
* Constructs a new JSONRequest instance.
*
* @constructor
* @param {Object} s Optional settings object.
*/
JSONRequest : function(s) {
this.settings = extend({
}, s);
this.count = 0;
},
/**#@+
* @method
*/
/**
* Sends a JSON-RPC call. Consult the Wiki API documentation for more details on what you can pass to this function.
*
* @param {Object} o Call object where there are three field id, method and params this object should also contain callbacks etc.
*/
send : function(o) {
var ecb = o.error, scb = o.success;
o = extend(this.settings, o);
o.success = function(c, x) {
c = JSON.parse(c);
if (typeof(c) == 'undefined') {
c = {
error : 'JSON Parse error.'
};
}
if (c.error)
ecb.call(o.error_scope || o.scope, c.error, x);
else
scb.call(o.success_scope || o.scope, c.result);
};
o.error = function(ty, x) {
ecb.call(o.error_scope || o.scope, ty, x);
};
o.data = JSON.serialize({
id : o.id || 'c' + (this.count++),
method : o.method,
params : o.params
});
// JSON content type for Ruby on rails. Bug: #1883287
o.content_type = 'application/json';
XHR.send(o);
},
'static' : {
/**
* Simple helper function to send a JSON-RPC request without the need to initialize an object.
* Consult the Wiki API documentation for more details on what you can pass to this function.
*
* @param {Object} o Call object where there are three field id, method and params this object should also contain callbacks etc.
*/
sendRPC : function(o) {
return new tinymce.util.JSONRequest().send(o);
}
}
/**#@-*/
});
}());

View File

@@ -0,0 +1,285 @@
/**
* $Id: URI.js 928 2008-09-14 15:14:22Z spocke $
*
* @author Moxiecode
* @copyright Copyright <20> 2004-2008, Moxiecode Systems AB, All rights reserved.
*/
(function() {
var each = tinymce.each;
/**#@+
* @class This class handles parsing, modification and serialization of URI/URL strings.
* @member tinymce.util.URI
*/
tinymce.create('tinymce.util.URI', {
/**
* Constucts a new URI instance.
*
* @constructor
* @param {String} u URI string to parse.
* @param {Object} s Optional settings object.
*/
URI : function(u, s) {
var t = this, o, a, b;
// Default settings
s = t.settings = s || {};
// Strange app protocol or local anchor
if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {
t.source = u;
return;
}
// Absolute path with no host, fake host and protocol
if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)
u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
// Relative path
if (u.indexOf(':/') === -1 && u.indexOf('//') !== 0)
u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
var s = u[i];
// Zope 3 workaround, they use @@something
if (s)
s = s.replace(/\(mce_at\)/g, '@@');
t[v] = s;
});
if (b = s.base_uri) {
if (!t.protocol)
t.protocol = b.protocol;
if (!t.userInfo)
t.userInfo = b.userInfo;
if (!t.port && t.host == 'mce_host')
t.port = b.port;
if (!t.host || t.host == 'mce_host')
t.host = b.host;
t.source = '';
}
//t.path = t.path || '/';
},
/**#@+
* @method
*/
/**
* Sets the internal path part of the URI.
*
* @param {string} p Path string to set.
*/
setPath : function(p) {
var t = this;
p = /^(.*?)\/?(\w+)?$/.exec(p);
// Update path parts
t.path = p[0];
t.directory = p[1];
t.file = p[2];
// Rebuild source
t.source = '';
t.getURI();
},
/**
* Converts the specified URI into a relative URI based on the current URI instance location.
*
* @param {String} u URI to convert into a relative path/URI.
* @return {String} Relative URI from the point specified in the current URI instance.
*/
toRelative : function(u) {
var t = this, o;
if (u === "./")
return u;
u = new tinymce.util.URI(u, {base_uri : t});
// Not on same domain/port or protocol
if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)
return u.getURI();
o = t.toRelPath(t.path, u.path);
// Add query
if (u.query)
o += '?' + u.query;
// Add anchor
if (u.anchor)
o += '#' + u.anchor;
return o;
},
/**
* Converts the specified URI into a absolute URI based on the current URI instance location.
*
* @param {String} u URI to convert into a relative path/URI.
* @param {bool} nh No host and protocol prefix.
* @return {String} Absolute URI from the point specified in the current URI instance.
*/
toAbsolute : function(u, nh) {
var u = new tinymce.util.URI(u, {base_uri : this});
return u.getURI(this.host == u.host ? nh : 0);
},
/**
* Converts a absolute path into a relative path.
*
* @param {String} base Base point to convert the path from.
* @param {String} path Absolute path to convert into a relative path.
*/
toRelPath : function(base, path) {
var items, bp = 0, out = '', i, l;
// Split the paths
base = base.substring(0, base.lastIndexOf('/'));
base = base.split('/');
items = path.split('/');
if (base.length >= items.length) {
for (i = 0, l = base.length; i < l; i++) {
if (i >= items.length || base[i] != items[i]) {
bp = i + 1;
break;
}
}
}
if (base.length < items.length) {
for (i = 0, l = items.length; i < l; i++) {
if (i >= base.length || base[i] != items[i]) {
bp = i + 1;
break;
}
}
}
if (bp == 1)
return path;
for (i = 0, l = base.length - (bp - 1); i < l; i++)
out += "../";
for (i = bp - 1, l = items.length; i < l; i++) {
if (i != bp - 1)
out += "/" + items[i];
else
out += items[i];
}
return out;
},
/**
* Converts a relative path into a absolute path.
*
* @param {String} base Base point to convert the path from.
* @param {String} path Relative path to convert into an absolute path.
*/
toAbsPath : function(base, path) {
var i, nb = 0, o = [];
// Split paths
base = base.split('/');
path = path.split('/');
// Remove empty chunks
each(base, function(k) {
if (k)
o.push(k);
});
base = o;
// Merge relURLParts chunks
for (i = path.length - 1, o = []; i >= 0; i--) {
// Ignore empty or .
if (path[i].length == 0 || path[i] == ".")
continue;
// Is parent
if (path[i] == '..') {
nb++;
continue;
}
// Move up
if (nb > 0) {
nb--;
continue;
}
o.push(path[i]);
}
i = base.length - nb;
// If /a/b/c or /
if (i <= 0)
return '/' + o.reverse().join('/');
return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');
},
/**
* Returns the full URI of the internal structure.
*
* @param {bool} nh Optional no host and protocol part. Defaults to false.
*/
getURI : function(nh) {
var s, t = this;
// Rebuild source
if (!t.source || nh) {
s = '';
if (!nh) {
if (t.protocol)
s += t.protocol + '://';
if (t.userInfo)
s += t.userInfo + '@';
if (t.host)
s += t.host;
if (t.port)
s += ':' + t.port;
}
if (t.path)
s += t.path;
if (t.query)
s += '?' + t.query;
if (t.anchor)
s += '#' + t.anchor;
t.source = s;
}
return t.source;
}
/**#@-*/
});
})();

View File

@@ -0,0 +1,424 @@
/**
* $Id: UnitTester.js 394 2007-11-15 18:05:17Z spocke $
*
* @author Moxiecode
* @copyright Copyright <20> 2004-2006, Moxiecode Systems AB, All rights reserved.
*/
(function() {
// Shorten names
var each = tinymce.each, DOM = tinymce.DOM;
/**#@+
* @class This class is a simple Unit testing class. Provides simple methods for
* test case and asserts execution.
* XML Parser class. This class is only available for the dev version of TinyMCE.
* @member tinymce.util.UnitTester
*/
tinymce.create('tinymce.util.UnitTester', {
/**
* Constructs a new UnitTester instance.
*
* @constructor
* @param {String} id Element ID to log execution events to.
* @param {Object} s Optional settings object.
*/
UnitTester : function(id, s) {
this.id = id;
this.cases = {};
this.settings = tinymce.extend({
debug : false,
log_skipped : false
}, s);
},
/**#@+
* @method
*/
/**
* Fakes a mouse event.
*
* @param {Element/String} e DOM element object or element id to send fake event to.
* @param {String} na Event name to fake like "click".
* @param {Object} o Optional object with data to send with the event like cordinates.
*/
fakeMouseEvent : function(e, na, o) {
var ev;
o = tinymce.extend({
screenX : 0,
screenY : 0,
clientX : 0,
clientY : 0
}, o);
e = DOM.get(e);
if (e.fireEvent) {
ev = document.createEventObject();
tinymce.extend(ev, o);
e.fireEvent('on' + na, ev);
return;
}
ev = document.createEvent('MouseEvents');
if (ev.initMouseEvent)
ev.initMouseEvent(na, true, true, window, 1, o.screenX, o.screenY, o.clientX, o.clientY, false, false, true, false, 0, null);
e.dispatchEvent(ev);
},
/**
* Fakes a key event.
*
* @param {Element/String} e DOM element object or element id to send fake event to.
* @param {String} na Event name to fake like "keydown".
* @param {Object} o Optional object with data to send with the event like keyCode and charCode.
*/
fakeKeyEvent : function(e, na, o) {
var ev;
o = tinymce.extend({
keyCode : 13,
charCode : 0
}, o);
e = DOM.get(e);
if (e.fireEvent) {
ev = document.createEventObject();
tinymce.extend(ev, o);
e.fireEvent('on' + na, ev);
return;
}
if (document.createEvent) {
try {
// Fails in Safari
ev = document.createEvent('KeyEvents');
ev.initKeyEvent(na, true, true, window, false, false, false, false, o.keyCode, o.charCode);
} catch (ex) {
ev = document.createEvent('Events');
ev.initEvent(na, true, true);
ev.keyCode = o.keyCode;
ev.charCode = o.charCode;
}
} else {
ev = document.createEvent('UIEvents');
if (ev.initUIEvent)
ev.initUIEvent(na, true, true, window, 1);
ev.keyCode = o.keyCode;
ev.charCode = o.charCode;
}
e.dispatchEvent(ev);
},
/**
* Adds a test with units.
*
* @param {String} n Name of test.
* @param {Object} t Name/Value collection with functions to be executed.
*/
add : function(n, t) {
this.cases[n] = t;
},
/**
* Resets the UnitTester and removes any contents from the log.
*/
reset : function() {
DOM.get(this.id).innerHTML = '';
},
/**
* TODO: FIX ME!
*/
runAsync : function(n, te) {
var t = this, c, st;
if (!t.started) {
st = t.stats = {
tests : 0,
asserts : 0,
failed_tests : 0,
failed_asserts : 0,
skipped_asserts : 0,
exceptions : 0,
total : 0
};
t.started = 1;
each(t.cases, function(c) {
each(c, function(x, k) {
if (k == 'setup' || k == 'teardown')
return;
if (te && k != te)
return;
st.total++;
});
});
}
c = t.cases[n];
if (c.setup)
c.setup.call(t);
each(c, function(v, k) {
if (k == 'setup' || k == 'teardown')
return;
if (te && k != te)
return;
st.tests++;
t.failedTest = 0;
t.assertCount = 0;
t.log('Running test: ' + n + '.' + k + ' (' + st.tests + '/' + st.total + ')');
if (!t.settings.debug) {
try {
v.call(t);
} catch (ex) {
t.logFailure('Exception occured:', ex);
st.exceptions++;
t.failedTest = 1;
}
} else
v.call(t);
if (t.failedTest)
st.failed_tests++;
});
if (c.teardown)
c.teardown.call(t);
if (st.tests >= st.total) {
if (st.failed_tests > 0) {
t.logFailure(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
t.logFailure(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
if (st.skipped_asserts > 0)
t.logFailure(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
} else {
t.logSuccess(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
t.logSuccess(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
if (st.skipped_asserts > 0)
t.logSuccess(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
}
t.started = 0;
}
},
/**
* Runs the test(s). Default is execution of all added tests and units.
*
* @param {String} Optional test name to execute.
* @param {String} Optional unit to execute inside the test.
*/
run : function(n, te) {
var t = this, st, o;
st = t.stats = {
tests : 0,
asserts : 0,
failed_tests : 0,
failed_asserts : 0,
skipped_asserts : 0,
exceptions : 0
};
if (n) {
o = {};
o[n] = this.cases[n];
} else
o = this.cases;
each(o, function(c, n) {
var tc = 0;
if (c.setup)
c.setup.call(t);
each(c, function(v, k) {
if (k == 'setup' || k == 'teardown')
return;
if (te && k != te)
return;
st.tests++;
t.failedTest = 0;
t.assertCount = 0;
t.log('Running test: ' + n + ', ' + k);
if (!t.settings.debug) {
try {
v.call(t);
} catch (ex) {
t.logFailure('Exception occured:', ex);
st.exceptions++;
t.failedTest = 1;
}
} else
v.call(t);
if (t.failedTest)
st.failed_tests++;
});
if (c.teardown)
c.teardown.call(t);
});
if (st.failed_tests > 0) {
t.logFailure(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
t.logFailure(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
if (st.skipped_asserts > 0)
t.logFailure(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
} else {
t.logSuccess(t.format('Runned %d of %d tests, %d failed.', st.tests, st.tests, st.failed_tests));
t.logSuccess(t.format('Runned %d of %d asserts, %d failed.', st.asserts, st.asserts, st.failed_asserts));
if (st.skipped_asserts > 0)
t.logSuccess(t.format('Due to browser bugs %d asserts where skipped.', st.skipped_asserts));
}
},
/**
* String format function.
*
* @param {String} s String with %d %s things that gets replaced.
* @param {Object} .. Optional arguments to be placed in string.
* @return {String} Formatted string.
*/
format : function(s) {
var i = 1, a = arguments;
return s.replace(/%([ds])/g, function(m, t) {
return '' + a[i++];
});
},
/**
* Checks if the specified input param is true.
*
* @param {bool} e Object/item to check if true.
* @param {String} m Optional message to output.
* @param {bool} sk Skip error output if this is true.
*/
is : function(e, m, sk) {
this.stats.asserts++;
if (!e)
this.fail(this.format(m || '[%d] Assert failed, value not true: %s', this.assertCount, e), sk);
this.assertCount++;
},
/**
* Checks if the specified input param equals another param.
*
* @param {Object} v1 Object/item to check.
* @param {Object} v2 Object/item to check.
* @param {String} m Optional message to output.
* @param {bool} sk Skip error output if this is true.
*/
eq : function(v1, v2, m, sk) {
this.stats.asserts++;
if (v1 !== v2)
this.fail(this.format(m || '[%d] Assert failed, values are not equal: was "%s", expected "%s"', this.assertCount, '' + v1, '' + v2), sk);
this.assertCount++;
},
/**
* Checks if the specified input param unequal to the other param.
*
* @param {Object} v1 Object/item to check.
* @param {Object} v2 Object/item to check.
* @param {String} m Optional message to output.
* @param {bool} sk Skip error output if this is true.
*/
neq : function(v1, v2, m, sk) {
this.stats.asserts++;
if (v1 == v2)
this.fail(this.format(m || '[%d] Assert failed, values are equal: %s, %s', this.assertCount, v1, v2), sk);
this.assertCount++;
},
/**
* Adds a failure message to the log.
*
* @param {String} m Message to output.
* @param {bool} sk Skip error output if this is true.
*/
fail : function(m, sk) {
var t = this;
if (sk) {
t.stats.skipped_asserts++;
if (t.settings.log_skipped)
t.log('Skipped: ' + m);
return;
}
t.stats.failed_asserts++;
t.failedTest = 1;
t.logFailure(m);
},
/**
* Logs a failure message.
*
* @param {string} .. Things to log.
*/
logFailure : function() {
var t = this;
DOM.add(DOM.get(t.id), 'div', {'class' : 'failure'}, DOM.encode(Array.prototype.join.call(arguments, ',')));
if (window.console && window.console.debug)
console.debug(arguments);
},
/**
* Logs a message.
*
* @param {string} .. Things to log.
*/
log : function() {
DOM.add(DOM.get(this.id), 'div', null, DOM.encode(Array.prototype.join.call(arguments, ',')).replace(/\r?\n/g, '<br />'));
},
/**
* Logs a success message.
*
* @param {string} .. Things to log.
*/
logSuccess : function() {
DOM.add(DOM.get(this.id), 'div', {'class' : 'success'}, DOM.encode(Array.prototype.join.call(arguments, ',')));
}
/**#@-*/
});
})();

View File

@@ -0,0 +1,80 @@
/**
* $Id: XHR.js 832 2008-05-02 11:01:57Z spocke $
*
* @author Moxiecode
* @copyright Copyright <20> 2004-2006, Moxiecode Systems AB, All rights reserved.
*/
/**#@+
* @class This class enables you to send XMLHTTPRequests cross browser.
* @member tinymce.util.XHR
* @static
*/
tinymce.create('static tinymce.util.XHR', {
/**#@+
* @method
*/
/**
* Sends a XMLHTTPRequest.
* Consult the Wiki for details on what settings this method takes.
*
* @param {Object} o Object will target URL, callbacks and other info needed to make the request.
*/
send : function(o) {
var x, t, w = window, c = 0;
// Default settings
o.scope = o.scope || this;
o.success_scope = o.success_scope || o.scope;
o.error_scope = o.error_scope || o.scope;
o.async = o.async === false ? false : true;
o.data = o.data || '';
function get(s) {
x = 0;
try {
x = new ActiveXObject(s);
} catch (ex) {
}
return x;
};
x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');
if (x) {
if (x.overrideMimeType)
x.overrideMimeType(o.content_type);
x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);
if (o.content_type)
x.setRequestHeader('Content-Type', o.content_type);
x.send(o.data);
function ready() {
if (!o.async || x.readyState == 4 || c++ > 10000) {
if (o.success && c < 10000 && x.status == 200)
o.success.call(o.success_scope, '' + x.responseText, x, o);
else if (o.error)
o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);
x = null;
} else
w.setTimeout(ready, 10);
};
// Syncronous request
if (!o.async)
return ready();
// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
t = w.setTimeout(ready, 10);
}
/**#@-*/
}
});