From: Magnus H. <leg...@us...> - 2011-08-20 19:04:55
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "emacs-jabber". The branch, namespace-prefixes has been created at 3dd51cf94e3da967a4678ab3c13d78c10ef43c8d (commit) - Log ----------------------------------------------------------------- commit 3dd51cf94e3da967a4678ab3c13d78c10ef43c8d Author: Magnus Henoch <leg...@us...> Date: Sat Aug 20 20:01:57 2011 +0100 First attempt at handling namespace prefixes Google Talk just started using namespace prefixes, e.g. <ros:query xmlns:ros="jabber:iq:roster">... something that jabber.el is completely unprepared for. This hack seems to restore status quo. * jabber-xml.el (jabber-xml-resolve-namespace-prefixes): New function. * jabber-core.el (jabber-filter): Call jabber-xml-resolve-namespace-prefixes for every incoming stanza. diff --git a/jabber-core.el b/jabber-core.el index 084f25e..b2a1fa5 100644 --- a/jabber-core.el +++ b/jabber-core.el @@ -911,7 +911,7 @@ DATA is any sexp." (sit-for 2))) (delete-region (point-min) (point)) - (fsm-send fsm (list :stanza (car xml-data))) + (fsm-send fsm (list :stanza (jabber-xml-resolve-namespace-prefixes (car xml-data)))) ;; XXX: move this logic elsewhere ;; We explicitly don't catch errors in jabber-process-input, ;; to facilitate debugging. diff --git a/jabber-xml.el b/jabber-xml.el index 878df60..88878fe 100644 --- a/jabber-xml.el +++ b/jabber-xml.el @@ -21,6 +21,8 @@ (require 'xml) (require 'jabber-util) +(eval-when-compile + (require 'cl)) (defun jabber-escape-xml (str) "escape strings for xml" @@ -221,6 +223,50 @@ any string character data of this node" ,@body)) (put 'jabber-xml-let-attributes 'lisp-indent-function 2) +(defun jabber-xml-resolve-namespace-prefixes (xml-data &optional default-ns prefixes) + (let ((node-name (jabber-xml-node-name xml-data)) + (attrs (jabber-xml-node-attributes xml-data))) + ;; First find any foo:xmlns attributes.. + (dolist (attr attrs) + (let ((attr-name (symbol-name (car attr)))) + (when (string-match "xmlns:" attr-name) + (let ((prefix (substring attr-name (match-end 0))) + (ns-uri (cdr attr))) + ;; A slightly complicated dance to never change the + ;; original value of prefixes (since the caller depends on + ;; it), but also to avoid excessive copying (which remove + ;; always does). Might need to profile and tweak this for + ;; performance. + (setq prefixes + (cons (cons prefix ns-uri) + (if (assoc prefix prefixes) + (remove (assoc prefix prefixes) prefixes) + prefixes))))))) + ;; If there is an xmlns attribute, it is the new default + ;; namespace. + (let ((xmlns (jabber-xml-get-xmlns xml-data))) + (when xmlns + (setq default-ns xmlns))) + ;; Now, if the node name has a prefix, replace it and add an + ;; "xmlns" attribute. Slightly ugly, but avoids the need to + ;; change all the rest of jabber.el at once. + (let ((node-name-string (symbol-name node-name))) + (when (string-match "\\(.*\\):\\(.*\\)" node-name-string) + (let* ((prefix (match-string 1 node-name-string)) + (unprefixed (match-string 2 node-name-string)) + (ns (assoc prefix prefixes))) + (if (null ns) + ;; This is not supposed to happen... + (message "jabber-xml-resolve-namespace-prefixes: Unknown prefix in %s" node-name-string) + (setf (car xml-data) (intern unprefixed)) + (setf (cadr xml-data) (cons (cons 'xmlns (cdr ns)) (delq 'xmlns attrs))))))) + ;; And iterate through all child elements. + (mapc (lambda (x) + (when (listp x) + (jabber-xml-resolve-namespace-prefixes x default-ns prefixes))) + (jabber-xml-node-children xml-data)) + xml-data)) + (provide 'jabber-xml) ;;; arch-tag: ca206e65-7026-4ee8-9af2-ff6a9c5af98a ----------------------------------------------------------------------- hooks/post-receive -- emacs-jabber |