Index: iris/include/xmpp.h =================================================================== --- iris/include/xmpp.h (revision 470311) +++ iris/include/xmpp.h (working copy) @@ -318,8 +318,11 @@ QDomDocument & doc() const; QString baseNS() const; + QString xhtmlImNS() const; + QString xhtmlNS() const; QDomElement createElement(const QString &ns, const QString &tagName); QDomElement createTextElement(const QString &ns, const QString &tagName, const QString &text); + QDomElement createXHTMLElement(const QString &xHTML); void appendChild(const QDomElement &e); Kind kind() const; @@ -372,6 +375,8 @@ virtual QDomDocument & doc() const=0; virtual QString baseNS() const=0; + virtual QString xhtmlImNS() const=0; + virtual QString xhtmlNS() const=0; virtual bool old() const=0; virtual void close()=0; @@ -479,6 +484,8 @@ // reimplemented QDomDocument & doc() const; QString baseNS() const; + QString xhtmlImNS() const; + QString xhtmlNS() const; bool old() const; void close(); Index: iris/include/im.h =================================================================== --- iris/include/im.h (revision 470311) +++ iris/include/im.h (working copy) @@ -65,6 +65,7 @@ QString lang() const; QString subject(const QString &lang="") const; QString body(const QString &lang="") const; + QString xHTMLBody(const QString &lang="") const; QString thread() const; Stanza::Error error() const; @@ -75,6 +76,7 @@ void setLang(const QString &s); void setSubject(const QString &s, const QString &lang=""); void setBody(const QString &s, const QString &lang=""); + void setXHTMLBody(const QString &s, const QString &lang="", const QString &attr = ""); void setThread(const QString &s); void setError(const Stanza::Error &err); @@ -286,6 +288,7 @@ bool canSearch() const; bool canGroupchat() const; bool canDisco() const; + bool canXHTML() const; bool isGateway() const; bool haveVCard() const; @@ -298,6 +301,7 @@ FID_Disco, FID_Gateway, FID_VCard, + FID_Xhtml, // private Psi actions FID_Add Index: iris/xmpp-im/types.cpp =================================================================== --- iris/xmpp-im/types.cpp (revision 470311) +++ iris/xmpp-im/types.cpp (working copy) @@ -19,7 +19,7 @@ */ #include"im.h" - +#include "protocol.h" #include #include @@ -180,7 +180,8 @@ Jid to, from; QString id, type, lang; - StringMap subject, body; + StringMap subject, body, xHTMLBody; + QString thread; Stanza::Error error; @@ -279,6 +280,11 @@ return d->body[lang]; } +QString Message::xHTMLBody(const QString &lang) const +{ + return d->xHTMLBody[lang]; +} + QString Message::thread() const { return d->thread; @@ -340,9 +346,16 @@ void Message::setBody(const QString &s, const QString &lang) { d->body[lang] = s; - //d->flag = false; } +void Message::setXHTMLBody(const QString &s, const QString &lang, const QString &attr) +{ + //ugly but needed if s is not a node but a list of leaf + + QString content = "\n" + s +"\n"; + d->xHTMLBody[lang] = content; +} + void Message::setThread(const QString &s) { d->thread = s; @@ -489,7 +502,19 @@ s.appendChild(e); } } - + if ( !d->xHTMLBody.isEmpty()) { + QDomElement parent = s.createElement(s.xhtmlImNS(), "html"); + for(it = d->xHTMLBody.begin(); it != d->xHTMLBody.end(); ++it) { + const QString &str = it.data(); + if(!str.isEmpty()) { + QDomElement child = s.createXHTMLElement(str); + if(!it.key().isEmpty()) + child.setAttributeNS(NS_XML, "xml:lang", it.key()); + parent.appendChild(child); + } + } + s.appendChild(parent); + } if(d->type == "error") s.setError(d->error); @@ -591,6 +616,21 @@ else if(e.tagName() == "thread") d->thread = e.text(); } + else if (e.namespaceURI() == s.xhtmlImNS()) { + if (e.tagName() == "html") { + QDomNodeList htmlNL= e.childNodes(); + for (unsigned int x = 0; x < htmlNL.count(); x++) { + QDomElement i = htmlNL.item(x).toElement(); + + if (i.tagName() == "body") { + QDomDocument RichText; + QString lang = i.attributeNS(NS_XML, "lang", ""); + RichText.appendChild(i); + d-> xHTMLBody[lang] = RichText.toString(); + } + } + } + } else { //printf("extension element: [%s]\n", e.tagName().latin1()); } @@ -1418,6 +1458,16 @@ return test(ns); } +#define FID_XHTML "http://jabber.org/protocol/xhtml-im" +bool Features::canXHTML() const +{ + QStringList ns; + + ns << FID_XHTML; + + return test(ns); +} + #define FID_GROUPCHAT "jabber:iq:conference" bool Features::canGroupchat() const { Index: iris/xmpp-im/xmpp_tasks.cpp =================================================================== --- iris/xmpp-im/xmpp_tasks.cpp (revision 470311) +++ iris/xmpp-im/xmpp_tasks.cpp (working copy) @@ -1348,6 +1348,10 @@ query.appendChild(feature); feature = doc()->createElement("feature"); + feature.setAttribute("var", "http://jabber.org/protocol/xhtml-im"); + query.appendChild(feature); + + feature = doc()->createElement("feature"); feature.setAttribute("var", "http://jabber.org/protocol/si/profile/file-transfer"); query.appendChild(feature); Index: iris/xmpp-core/protocol.h =================================================================== --- iris/xmpp-core/protocol.h (revision 470311) +++ iris/xmpp-core/protocol.h (working copy) @@ -35,6 +35,8 @@ #define NS_SESSION "urn:ietf:params:xml:ns:xmpp-session" #define NS_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas" #define NS_BIND "urn:ietf:params:xml:ns:xmpp-bind" +#define NS_XHTML_IM "http://jabber.org/protocol/xhtml-im" +#define NS_XHTML "http://www.w3.org/1999/xhtml" namespace XMPP { Index: iris/xmpp-core/stream.cpp =================================================================== --- iris/xmpp-core/stream.cpp (revision 470311) +++ iris/xmpp-core/stream.cpp (working copy) @@ -293,6 +293,16 @@ return d->s->baseNS(); } +QString Stanza::xhtmlImNS() const +{ + return d->s->xhtmlImNS(); +} + +QString Stanza::xhtmlNS() const +{ + return d->s->xhtmlNS(); +} + QDomElement Stanza::createElement(const QString &ns, const QString &tagName) { return d->s->doc().createElementNS(ns, tagName); @@ -305,6 +315,16 @@ return e; } +QDomElement Stanza::createXHTMLElement(const QString &xHTML) +{ + QDomDocument doc; + + doc.setContent(xHTML, true); + QDomElement root = doc.documentElement(); + //QDomElement e; + return (root); +} + void Stanza::appendChild(const QDomElement &e) { d->e.appendChild(e); @@ -861,6 +881,16 @@ return NS_CLIENT; } +QString ClientStream::xhtmlImNS() const +{ + return NS_XHTML_IM; +} + +QString ClientStream::xhtmlNS() const +{ + return NS_XHTML; +} + void ClientStream::setAllowPlain(bool b) { d->allowPlain = b;