xmlTextNode: function (text)
{
if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLDOM").createTextNode(text);
} else {
return document.createTextNode(text);
}
},
/** Function: getText
* Get the concatenation of all text children of an element.
*
* Parameters:
* (XMLElement) elem - A DOM element.
*
* Returns:
* A String with the concatenated text of all text element children.
*/
getText: function (elem)
{
if (!elem) return null;
var str = "";
if (elem.childNodes.length === 0 && elem.nodeType ==
Strophe.ElementType.TEXT) {
str += elem.nodeValue;
}
for (var i = 0; i < elem.childNodes.length; i++) {
if (elem.childNodes[i].nodeType == Strophe.ElementType.TEXT) {
str += elem.childNodes[i].nodeValue;
}
}
return str;
},
/** Function: copyElement
* Copy an XML DOM element.
*
* This function copies a DOM element and all its descendants and returns
* the new copy.
*
* Parameters:
* (XMLElement) elem - A DOM element.
*
* Returns:
* A new, copied DOM element tree.
*/
copyElement: function (elem)
{
var i, el;
if (elem.nodeType == Strophe.ElementType.NORMAL) {
el = Strophe.xmlElement(elem.tagName);
for (i = 0; i < elem.attributes.length; i++) {
el.setAttribute(elem.attributes[i].nodeName.toLowerCase(),
elem.attributes[i].value);
}
for (i = 0; i < elem.childNodes.length; i++) {
el.appendChild(Strophe.copyElement(elem.childNodes[i]));
}
} else if (elem.nodeType == Strophe.ElementType.TEXT) {
el = Strophe.xmlTextNode(elem.nodeValue);
}
return el;
},
/** Function: escapeJid
* Escape a JID.
*
* Parameters:
* (String) jid - A JID.
*
* Returns:
* An escaped JID String.
*/
escapeJid: function (jid)
{
var user = jid.split("@");
if (user.length == 1)
// no user so nothing to escape
return jid;
var host = user.splice(user.length - 1, 1)[0];
user = user.join("@")
.replace(/^\s+|\s+$/g, '')
.replace(/\\/g, "\\5c")
.replace(/ /g, "\\20")
.replace(/\"/g, "\\22")
.replace(/\&/g, "\\26")
.replace(/\'/g, "\\27")
.replace(/\//g, "\\2f")
.replace(/:/g, "\\3a")
.replace(/</g, "\\3c")
.replace(/>/g, "\\3e")
.replace(/@/g, "\\40");
return [user, host].join("@");
},
/** Function: unescapeJid
* Unescape a JID.
*
* Parameters:
* (String) jid - A JID.
*
* Returns:
* An unescaped JID String.
*/
unescapeJid: function (jid)
{
return jid.replace(/\\20/g, " ")
.replace(/\\22/g, '"')
.replace(/\\26/g, "&")
.replace(/\\27/g, "'")
.replace(/\\2f/g, "/")
.replace(/\\3a/g, ":")
.replace(/\\3c/g, "<")
.replace(/\\3e/g, ">")
.replace(/\\40/g, "@")
.replace(/\\5c/g, "\\");
},
/** Function: getNodeFromJid
* Get the node portion of a JID String.
*
* Parameters:
* (String) jid - A JID.
*
* Returns:
* A String containing the node.
*/
getNodeFromJid: function (jid)
{
if (jid.indexOf("@") < 0)
return null;
return Strophe.escapeJid(jid).split("@")[0];
},
/** Function: getDomainFromJid
* Get the domain portion of a JID String.
*
* Parameters:
* (String) jid - A JID.
*
* Returns:
* A String containing the domain.
*/
getDomainFromJid: function (jid)
{
var bare = Strophe.escapeJid(Strophe.getBareJidFromJid(jid));
if (bare.indexOf("@") < 0)
return bare;
else
return bare.split("@")[1];
},
/** Function: getResourceFromJid
* Get the resource portion of a JID String.
*
* Parameters:
* (String) jid - A JID.
*
* Returns:
* A String containing the resource.
*/
getResourceFromJid: function (jid)
{
var s = Strophe.escapeJid(jid).split("/");
if (s.length < 2) return null;
return s[1];
},
/** Function: getBareJidFromJid
* Get the bare JID from a JID String.
*
* Parameters:
* (String) jid - A JID.
*
* Returns:
* A String containing the bare JID.
*/
getBareJidFromJid: function (jid)
{
return this.escapeJid(jid).split("/")[0];
},
/** Function: log
* User overrideable logging function.
*
* This function is called whenever the Strophe library calls any
* of the logging functions. The default implementation of this
* function does nothing. If client code wishes to handle the logging
* messages, it should override this with
* > Strophe.log = function (level, msg) {
* > (user code here)
* > };
*
* Please note that data sent and received over the wire is logged
* via Strophe.Connection.rawInput() and Strophe.Connection.rawOutput().
*
* The different levels and their meanings are
*
* DEBUG - Messages useful for debugging purposes.
* INFO - Informational messages. This is mostly information like
* 'disconnect was called' or 'SASL auth succeeded'.
* WARN - Warnings about potential problems. This is mostly used
* to report transient connection errors like request timeouts.
* ERROR - Some error occurred.
* FATAL - A non-recoverable fatal error occurred.
*
* Parameters:
* (Integer) level - The log level of the log message. This will
* be one of the values in Strophe.LogLevel.
* (String) msg - The log message.
*/
log: function (level, msg)
{
return;
},
/** Function: debug
* Log a message at the Strophe.LogLevel.DEBUG level.
*
* Parameters:
* (String) msg - The log message.
*/
debug: function(msg)
{
this.log(this.LogLevel.DEBUG, msg);
},
/** Function: info
* Log a message at the Strophe.LogLevel.INFO level.
*
* Parameters:
* (String) msg - The log message.
*/
info: function (msg)
{
this.log(this.LogLevel.INFO, msg);
},
/** Function: warn
* Log a message at the Strophe.LogLevel.WARN level.
*
* Parameters:
* (String) msg - The log message.
*/
warn: function (msg)
{
this.log(this.LogLevel.WARN, msg);
},
/** Function: error
* Log a message at the Strophe.LogLevel.ERROR level.
*
* Parameters:
* (String) msg - The log message.
*/
error: function (msg)
{
this.log(this.LogLevel.ERROR, msg);
},
/** Function: fatal
* Log a message at the Strophe.LogLevel.FATAL level.
*
* Parameters:
* (String) msg - The log message.
*/
fatal: function (msg)
{
this.log(this.LogLevel.FATAL, msg);
},
/** Function: serialize
* Render a DOM element and all descendants to a String.
*
* Parameters:
* (XMLElement) elem - A DOM element.
*
* Returns:
* The serialized element tree as a String.
*/
serialize: function (elem)
{
var result;
if (!elem) return null;
var nodeName = elem.nodeName;
var i, child;
if (elem.getAttribute("_realname")) {
nodeName = elem.getAttribute("_realname");
}
result = "<" + nodeName;
for (i = 0; i < elem.attributes.length; i++) {
if(elem.attributes[i].nodeName != "_realname") {
result += " " + elem.attributes[i].nodeName.toLowerCase() +
"='" + elem.attributes[i].value
.replace("'", "'").replace("&", "&") + "'";
}
}
if (elem.childNodes.length > 0) {
result += ">";
for (i = 0; i < elem.childNodes.length; i++) {
child = elem.childNodes[i];
if (child.nodeType == Strophe.ElementType.NORMAL) {
// normal element, so recurse
result += Strophe.serialize(child);
} else if (child.nodeType == Strophe.ElementType.TEXT) {
// text element
result += child.nodeValue;
}
}
result += "</" + nodeName + ">";
} else {
result += "/>";
}
return result;
},
/** PrivateVariable: _requestId
* _Private_ variable that keeps track of the request ids for
* connections.
*/
_requestId: 0
};
/** Class: Strophe.Builder