Software /
code /
prosody
Comparison
util/stanza.lua @ 9924:5a2e53bef031
util.stanza: Fix :top_tag() handling of namespaced attributes
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 25 Mar 2019 14:37:43 +0000 |
parent | 9732:51583ea2b4fd |
child | 10116:4807535b8673 |
comparison
equal
deleted
inserted
replaced
9923:e83dfcdeab59 | 9924:5a2e53bef031 |
---|---|
268 end | 268 end |
269 self = self:get_child(name, xmlns); | 269 self = self:get_child(name, xmlns); |
270 until not self | 270 until not self |
271 end | 271 end |
272 | 272 |
273 local function _clone(stanza, only_top) | |
274 local attr, tags = {}, {}; | |
275 for k,v in pairs(stanza.attr) do attr[k] = v; end | |
276 local old_namespaces, namespaces = stanza.namespaces; | |
277 if old_namespaces then | |
278 namespaces = {}; | |
279 for k,v in pairs(old_namespaces) do namespaces[k] = v; end | |
280 end | |
281 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; | |
282 if not only_top then | |
283 for i=1,#stanza do | |
284 local child = stanza[i]; | |
285 if child.name then | |
286 child = _clone(child); | |
287 t_insert(tags, child); | |
288 end | |
289 t_insert(new, child); | |
290 end | |
291 end | |
292 return setmetatable(new, stanza_mt); | |
293 end | |
294 | |
295 local function clone(stanza, only_top) | |
296 if not is_stanza(stanza) then | |
297 error("bad argument to clone: expected stanza, got "..type(stanza)); | |
298 end | |
299 return _clone(stanza, only_top); | |
300 end | |
273 | 301 |
274 local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; | 302 local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; |
275 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end | 303 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end |
276 | 304 |
277 local function _dostring(t, buf, self, _xml_escape, parentns) | 305 local function _dostring(t, buf, self, _xml_escape, parentns) |
308 _dostring(t, buf, _dostring, xml_escape, nil); | 336 _dostring(t, buf, _dostring, xml_escape, nil); |
309 return t_concat(buf); | 337 return t_concat(buf); |
310 end | 338 end |
311 | 339 |
312 function stanza_mt.top_tag(t) | 340 function stanza_mt.top_tag(t) |
313 local attr_string = ""; | 341 local top_tag_clone = clone(t, true); |
314 if t.attr then | 342 return tostring(top_tag_clone):sub(1,-3)..">"; |
315 for k, v in pairs(t.attr) do if type(k) == "string" then attr_string = attr_string .. s_format(" %s='%s'", k, xml_escape(tostring(v))); end end | |
316 end | |
317 return s_format("<%s%s>", t.name, attr_string); | |
318 end | 343 end |
319 | 344 |
320 function stanza_mt.get_text(t) | 345 function stanza_mt.get_text(t) |
321 if #t.tags == 0 then | 346 if #t.tags == 0 then |
322 return t_concat(t); | 347 return t_concat(t); |
384 stanza:add_direct_child(child); | 409 stanza:add_direct_child(child); |
385 end | 410 end |
386 end | 411 end |
387 return stanza; | 412 return stanza; |
388 end | 413 end |
389 end | |
390 | |
391 local function _clone(stanza) | |
392 local attr, tags = {}, {}; | |
393 for k,v in pairs(stanza.attr) do attr[k] = v; end | |
394 local old_namespaces, namespaces = stanza.namespaces; | |
395 if old_namespaces then | |
396 namespaces = {}; | |
397 for k,v in pairs(old_namespaces) do namespaces[k] = v; end | |
398 end | |
399 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; | |
400 for i=1,#stanza do | |
401 local child = stanza[i]; | |
402 if child.name then | |
403 child = _clone(child); | |
404 t_insert(tags, child); | |
405 end | |
406 t_insert(new, child); | |
407 end | |
408 return setmetatable(new, stanza_mt); | |
409 end | |
410 | |
411 local function clone(stanza) | |
412 if not is_stanza(stanza) then | |
413 error("bad argument to clone: expected stanza, got "..type(stanza)); | |
414 end | |
415 return _clone(stanza); | |
416 end | 414 end |
417 | 415 |
418 local function message(attr, body) | 416 local function message(attr, body) |
419 if not body then | 417 if not body then |
420 return new_stanza("message", attr); | 418 return new_stanza("message", attr); |