xmppjs / ltx Goto Github PK
View Code? Open in Web Editor NEWXML for JavaScript
License: MIT License
XML for JavaScript
License: MIT License
See https://github.com/legastero/ltx-dom/blob/master/element.js
Alternatively we could consider switching to ltx-dom
itself?
loading of modules ['./sax_expat.js', './sax_ltx.js', /'./sax_easysax.js', './sax_node-xml.js',/ './sax_saxjs.js'] not run properly in browser. Any suggestion to define the default parser for browserify.
Thanks
Tommy Tang
I did a new install of our project this morning and discovered our test failing at toJSON
.
Looks like this was caused by changes in PR #91 to remove the toJSON
method. Shouldn't any removals should made in an backwards incompatible manner be a bump in major version?
@sonnyp if you want I can create a PR to put this back. Thanks!
ltx.Parser abstraction over the different ltx 'backends' doesn't emit startElement
, endElement
, ... events
Instead of the very short and not expressive function names, it would be better to have more self explanatory function names, like 'childNode' and 'text' and so on
The sax_ltx.js
SAX parser only unescapes the basic named XML entities, and not entities of the form &#x[XX];
Discovered this because of this change in Prosody: http://hg.prosody.im/trunk/rev/6e67c73f730c
So messages that contain newlines end up including 

instead of \n
when parsed in the browser. The parser for the node.js side handles these entities as expected.
Lets see the example provided in README:
el = new ltx.Element('root').
c('children');
el.c('child', { age: 5 }).t('Hello').up()
.c('child', { age: 7 }).t('Hello').up()
.c('child', { age: 99 }).t('Hello').up()
console.log("Serialized document:", el.root().toString());
Output of the above code is:
Serialized document: <root><children><child age="5">Hello</child><child age="7">Hello</child><child age="99">Hello</child></children></root>
But if we change the code to:
el = new ltx.Element('root');
el.c('children', { xmlns: NS_PRIVACY })
.c('child', { age: 5 }).t('Hello').up()
el.c('child', { age: 7 }).t('Hello').up()
.c('child', { age: 99 }).t('Hello').up();
console.log("Serialized document:", el.root().toString());
Output changes to:
Serialized document: <root><children><child age="5">Hello</child></children><child age="7">Hello</child><child age="99">Hello</child></root>
This might be a desired behaviour.
But what if I don't know all my children beforehand and want to include every child one by one in loop. Code would look like:
el = new ltx.Element('root');
el.c('children', { xmlns: NS_PRIVACY });
foreach children as child do
.c('child', { age: child[age] }).t('Hello').up()
end
console.log("Serialized document:", el.root().toString());
This will give the output:
Serialized document: <root><children /><child age="5">Hello</child><child age="7">Hello</child><child age="99">Hello</child></root>
How should I deal with this?
Hi, im using a library that depends on ltx. When updated to 2.7.2 i started to get an error with gulp-uglify:
message: "Unexpected character '`'",
stack: "Error at new JS_Parse_Error (eval at <anonymous>
(.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:1:0)...
The line where apparently contains the error its 39 on ltx/lib/escape.js
:
...
throw new Error(`Illegal XML character 0x${num.toString(16)}`)
...
The use of es6 string template in the latest changes.
Hope you can help me. For now i downgrade ltx to 2.7.1 and works perfectly.
Thanks
See #35
Example Code:
var tmp = new xmpp.Element('presence', { to: room_jid+'/'+room_nick })
.c('x', { xmlns: 'http://jabber.org/protocol/muc' })
.c('history', {"maxchars": 0} )
.root();
console.log(tmp.toString());
Prints:
''
Should Print:
''
The fix for line 199 in element.js is replace
if (v || v === ''){
with
if (v || v === '' || v === 0) {
Hi,
If you create an element and add a number as text, getText()
will not return the expected value:
> new ltx.Element("max").t(1000).getText();
''
> new ltx.Element("max").t('1000').getText();
'1000'
I guess checking if a child is a string is a little too restrictive. Could you please allow for numbers too?
Thanks in advance.
(Edit: removed silly comment: I noticed this bug because of something stupid in my code, not in anyone else's. But this is still a little annoying :))
ltx.parse('<o/>f')
ltx.parse('<o></o>f<b/>')
ltx.parse('<o>f</b>')
should fail, currently extra data is ignored
see #69
Currently, I am working on an XMPP project. This project should be supported in IE8. But I found IE8 could not support Object.defineProperty. So some codes in DOMElement.js will break the project.
I have tried to use es5-sham.js and es5-shim.js to solve this question, but I found Object.defineProperty implemented in es5-sham.js was via defineGetter and defineSetter. These two functions are still not implemented in IE8. Who could help me? Thank you in advance.
toJSON
DOMElement
bundle.js
in favor of dist/ltx.js
clone
(maybe), nameEquals
, attrsEquals
, childrenEquals
, equals
on Element
'
rather than "
for attributesThe instanceof operator was working for Element class proper to upgrade from 0.3.X to 0.4. It is now returning false.
ltx = require("ltx")
el = new ltx.Element('root').
c('children')
el.c('child', { age: 5 }).t('Hello').up()
.c('child', { age: 7 }).t('Hello').up()
.c('child', { age: 99 }).t('Hello').up()
console.log (el instanceof ltx.Element)
The output details are below... suggestion for windows, since binary compatibility is pretty much ensured... Have the install/post-install script simply download a prebuilt binary of ltx (x86, or x64, not sure if WinRT (arm) is supported with Node.js).
C:\Users\michaelr>npm -g install ltx
npm http GET https://registry.npmjs.org/ltx
npm http 304 https://registry.npmjs.org/ltx
npm http GET https://registry.npmjs.org/node-expat
npm http GET https://registry.npmjs.org/sax
npm http 304 https://registry.npmjs.org/node-expat
npm http 304 https://registry.npmjs.org/sax
> [email protected] install C:\Users\michaelr\AppData\Roaming\npm\node_modules\ltx\node_modules\node-expat
> node-gyp rebuild
C:\Users\michaelr\AppData\Roaming\npm\node_modules\ltx\node_modules\node-expat>node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
node-expat.cc
..\node-expat.cc(6): fatal error C1083: Cannot open include file: 'expat.h': No such file or directory [C:\Users\michaelr\AppData\Roaming\npm\node_modules\ltx\node_modules\node-expat\build\node_expa
.vcxproj]
gyp ERR! build error
gyp ERR! stack Error: `C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe` failed with exit code: 1
gyp ERR! stack at ChildProcess.onExit (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\build.js:219:23)
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:91:17)
gyp ERR! stack at Process._handle.onexit (child_process.js:678:10)
gyp ERR! System Windows_NT 6.1.7601
gyp ERR! command "node" "C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd C:\Users\michaelr\AppData\Roaming\npm\node_modules\ltx\node_modules\node-expat
gyp ERR! node -v v0.8.9
gyp ERR! node-gyp -v v0.6.8
gyp ERR! not ok
npm ERR! [email protected] install: `node-gyp rebuild`
npm ERR! `cmd "/c" "node-gyp rebuild"` failed with 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is most likely a problem with the node-expat package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-gyp rebuild
npm ERR! You can get their info via:
npm ERR! npm owner ls node-expat
npm ERR! There is likely additional logging output above.
npm ERR! System Windows_NT 6.1.7601
npm ERR! command "C:\\Program Files\\nodejs\\\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "-g" "install" "ltx"
npm ERR! cwd C:\Users\michaelr
npm ERR! node -v v0.8.9
npm ERR! npm -v 1.1.61
npm ERR! code ELIFECYCLE
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! C:\Users\michaelr\npm-debug.log
npm ERR! not ok code 0
I think https://github.com/node-xmpp/ltx/blob/master/lib/element.js#L12 is wrong and we should 'clone' the passed object.
So that if the original object is modified the Element attrs object isn't.
There are at least 2 workarounds right now for that issue:
https://github.com/node-xmpp/node-xmpp-core/blob/master/lib/stanza.js#L13
https://github.com/node-xmpp/ltx/blob/master/lib/element.js#L265
What do you think?
A third attribute could be accepted as child text node for the new element.
While building XML I often find myself thinking it would come handy.
What do you think?
The repro case:
const parseXml = require('ltx/lib/parse');
const tree = parseXml('<a><b><![CDATA[]]></b><b><![CDATA[--><c>&d;]]></b></a>');
console.log('Done:', !!tree);
Produces:
.../node_modules/ltx/lib/escape.js:44
throw new Error('Illegal XML entity ' + match)
^
Error: Illegal XML entity &d;
at unescapeXMLReplace (.../node_modules/ltx/lib/escape.js:44:9)
at unescapeXML (.../node_modules/ltx/lib/escape.js:59:7)
at SaxLtx.write (.../node_modules/ltx/lib/parsers/ltx.js:94:33)
at Parser.write (.../node_modules/ltx/lib/Parser.js:56:15)
at parse (.../node_modules/ltx/lib/parse.js:23:5)
at Object.<anonymous> (.../scripts/bug.js:2:14)
at Module._compile (internal/modules/cjs/loader.js:945:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:962:10)
at Module.load (internal/modules/cjs/loader.js:798:32)
at Function.Module._load (internal/modules/cjs/loader.js:711:12)
I am using node-xmpp and it uses ltx. I recently had occasion to need to .clone() an element and I found some trouble. I normally was accessing top-level element properties (attributes) via...
stanza.from
stanza.to
stanza.type
rather than
stanza.attrs.from
stanza.attrs.to
stanza.attrs.type
This worked fine on the original Element. However, after the following...
var newstanza = stanza.clone();
I find that....
newstanza.from is null while newstanza.attrs.from still works just fine.
So it seems the top-level property accessors are not cloned during the clone operation.
look like Element.write breaks unicode symbols when sending them chunked over a socket.
problem spotted over at xmppjs/xmpp.js#198
Recent commit contained this change (and more):
-* `getChild(name, xmlns?)`: find one children +* `getChild(name, xmlns?)`: find first children
Old string was clearly linguistically wrong: children is plural, a single one is a child.
New string is correct if it result is (potentially) plural, else it should be "find first child".
...and similarly for getChildByAttr() and possibly other places.
The raw xml string:
<a>
>a
</a>
Turn it into parsed result object:
const result = ltx.parse(rawXml);
when use ltx.stringify(result)
against the parsed result object, it gives out the following incorrect output:
<a>
>a
<a>
I checked the source codes and the unit tests, it seems that the result.toString()
gives out the correct string because it do escape, but ltx.stringify
does not.
Hi! While working on the entity expansion, I found that the actual entity replacement is done using a regular expression. I know it's a micro-optimization, but I was able to shave 20% off parsing a typical (15-kilobyteish) document by replacing the regular expression with an indexOf loop.
I can open a PR with the code changes if this is interesting:
$ git diff --staged
diff --git a/lib/escape.js b/lib/escape.js
index 5fd682e..dbf023f 100644
--- a/lib/escape.js
+++ b/lib/escape.js
@@ -46,7 +46,22 @@ exports.escapeXML = function escapeXML (s) {
}
exports.unescapeXML = function unescapeXML (s) {
- return s.replace(/&(amp|lt|gt|quot|apos|#x[0-9a-fA-F]+|#[0-9]+);/g, unescapeXMLReplace)
+ var result = ''
+ var start = -1
+ var end = -1
+ var previous = 0
+ while ((start = s.indexOf('&', previous)) !== -1 && (end = s.indexOf(';', start + 1))) {
+ // if (previous != start)
+ result = result +
+ s.substring(previous, start) +
+ unescapeXMLReplace(s.substring(start, end + 1))
+ previous = end + 1
+ }
+
+ // push the remaining characters
+ result = result + s.substring(previous)
+
+ return result
}
exports.escapeXMLText = function escapeXMLText (s) {
I do understand that it increases complexity; but this code, if anything in an XML parser is "hot" code and needs to run fast.
Please, I need only this one file. :-)
ltx.parse("<x> </x>").children.length
is 1
and correct (as long as whitespace characters where threated as children)
ltx.parse("<x> <y> </y> </x>").children.length
is 3
and NOT correct; it should be 1
The children and the text of an element are treated the same way. Maybe we should explicitly separate them? So an element has either some children (el.children
) or content (el.content
) but not both.
Disclaimer: I may have just missed something.
When using the ltx/lib/parsers/ltx
parser and processing a stream, there doesn't appear to be an end
event (or similar) that I can listen for to confirm that parsing has completed. Any chance of one being added or is it for us to derive?
Cheers
Hi
I am using node-xmpp-client module and want to send HTML messages to client.
Below is my code snippet which doesn't work due to obvious reasons.
Can you suggest how to send HTML messages?
Thanks
Saurabh
if (stanza.is('message') && stanza.attrs.type === 'chat' ) {
var reply = new xmpp.Client.Stanza('message', {
to: stanza.attrs.from,
from: stanza.attrs.to,
type: 'chat'
})
reply.c('body').t("<a href='http://www.google.com'>Google</a>);
console.log(firstMessage)
if (firstMessage)
{
firstMessage = false
}
else{
firstMessage = true;
client.send(reply);
}
}
This relates to really old versions of nodejs , specifically 0.12.x. Basically the work in #126 destroys anyone using older versions of node-xmpp-server on 0.12.x because of the use of CONST. The issue is the fact that for instance node-xmpp-core has a dep of ltx ^2.2.0 which means that npm will select 2.8.0 which blows up if you are using 0.12.x.
I understand the need to use new ES6 code but priority should be taken to not blow up older versions. This is why it should have been in 3.0.
2018-10-16 13:27 -04:00: lets-chat/node_modules/node-xmpp-server/node_modules/node-xmpp-core/node_modules/ltx/lib/parsers/ltx.js:68
const lt = data.indexOf('<', pos)
^^^^^
SyntaxError: Use of const in strict mode.
Hi,
I'm using a library which depends on lxt (https://github.com/otalk/jxt) and when I run UglifyJS through webpack on my build I get:
ERROR in 3-chunk41c1d9e763e90e289c4a.js from UglifyJs
SyntaxError: Unexpected token: operator (>) [./~/ltx/lib/stringify.js:9,0][3-chunk41c1d9e763e90e289c4a.js:44960,37]
This worked well until yesterday and I was able to build just fine. Do you think it has something to do with the latest changes?
Thanks!
To allow something like
function m (bar) {
return ltx`<foo bar='${bar}'>`
}
m(undefined)
to return <foo/>
maybe even
function m (bar) {
return ltx`<foo><${bar}/></foo>`
}
m(undefined)
to return <foo/>
LTx parser writes the DOM with HTML encoding by default.
<tag name="NodeName" websiteName="ValueOfWebsiteName" connectionStrinng="{name: 'myconnection'}" />
gets replaced to
<tag name="NodeName" websiteName="ValueOfWebsiteName" connectionStrinng="{name: 'myconnection'}"/>
When looking at the code,it is found that encoding is made by default. Should it be made optional ?
My XML file has other tags with HTML encoded strings. So, I am unable to use unescapeXML function while converting to string.
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
npm WARN package.json [email protected] 'repositories' (plural) Not supported.
npm WARN package.json Please pick one as the 'repository' field
npm WARN package.json [email protected] 'repositories' (plural) Not Supported.
So webpack treats dynamic requires differently to browserify, which means by default ltx fails when building under webpack.
Given that https://github.com/node-xmpp/ltx/blob/master/lib/parse.js#L11-L33 are always going to be an exception in browserify, and reason not to pull them out and only run this code in node?
I can submit a PR, just wanna check there's no good reason for it being this way?
During conversion from XML to DOM tree and then writing back DOM to file, it losses are the connects and CDATA content.
I have left the comment here bb8980e
Hello Team,
While trying to parse an xml document with multi-line comment , getting error Incomplete document.
running "vows --spec" emits the following:
parsing ✗ simple document TypeError: Object [object Object] has no method 'addListener' at new (/srv/data/jonas-src/GITauth/alioth/pkg-javascript/ltx/lib/parse.js:17:17) at Object.parse (/srv/data/jonas-src/GITauth/alioth/pkg-javascript/ltx/lib/parse.js:67:13) at Object. (/srv/data/jonas-src/GITauth/alioth/pkg-javascript/ltx/test/parse-test.js:8:26) at runTest (/usr/lib/nodejs/vows.js:132:26) at EventEmitter. (/usr/lib/nodejs/vows.js:78:9) at EventEmitter. (events.js:81:20) at EventEmitter.emit (/usr/lib/nodejs/vows.js:236:24) at Array.0 (/usr/lib/nodejs/vows/suite.js:162:45) at EventEmitter._tickCallback (node.js:126:26) ✗ text with commas TypeError: Object [object Object] has no method 'addListener' at new (/srv/data/jonas-src/GITauth/alioth/pkg-javascript/ltx/lib/parse.js:17:17) at Object.parse (/srv/data/jonas-src/GITauth/alioth/pkg-javascript/ltx/lib/parse.js:67:13) at Object. (/srv/data/jonas-src/GITauth/alioth/pkg-javascript/ltx/test/parse-test.js:13:19) at runTest (/usr/lib/nodejs/vows.js:132:26) at EventEmitter. (/usr/lib/nodejs/vows.js:78:9) at EventEmitter. (events.js:81:20) at EventEmitter.emit (/usr/lib/nodejs/vows.js:236:24) at Array.0 (/usr/lib/nodejs/vows/suite.js:162:45) at EventEmitter._tickCallback (node.js:126:26) ✓ erroneous document raises error ✓ incomplete document raises error
Is there a safe way to add an existing element as the child of another?
Overloading the 'c' method may be nice. If the value is another element then simply clone the element and append.
var someExistingElement = new Element('bar', {'a':'b'});
new Element('foo')
.c('bling').t('some text').up()
.c(someExistingElement)
Would result in:
<foo>
<bling>some text</bling>
<bar a='b' />
</foo>
The getChild
, getChildren
and getChildText
methods behave inconsistently on prefixed elements.
Example:
el = ltx.parse('<root><x:foo>bar</x:foo></root>');
el.getChildText('x:foo')
// result: 'bar'
el.getChildText('foo')
// result: null
el.getChild('x:foo')
// result: null -> can't try getText :-)
el.getChild('foo').getText()
// result: 'bar'
getChildText
uses this.name
to find the child while getChildren
, and thus getChild
, uses this.getName()
. However, this behavior should be consistent to avoid confusion and bugs.
Hi!
We've been using ltx for some time and loved it!
Now, when updating the deps we noticed that something changed and broke our code.
For example, if you the following element:
<person name="julien" job:title="hacker" />
where the job
namespace has been previously defined, you'd use element.attrs['job:title']
to access it. In the latest version of the code, we found that the namespaces are rewritten in the form of ns1
, ns2
... etc.
Even though this is probably correct this certainly breaks the code of our app, and I don't think we're the only one. The right behavior would be to find the righ nsX
based on the namespace's url and then get the attribute's value thru element.attrs['nsK:title']
, which is quite cumbersome.
I'm thinking having a getAttr(name, url)
method would be an elegant way. I'm preparing a PR with that if you don't mind. Let me know what tou think!
Related to the discussion in #37. Currently if you want all child elements you need to do el.getChildrenByFilter(function(c) { return c instanceof ltx.Element })
to get all child elements while excluding text nodes.
I suggested a new getChildElements()
method that does the filter.
Another option would be to change getChildren(name,xmlns)
to return all elements if both name
and xmlns
are null. Currently getChildren
will always return an empty list when name
is null.
I will submit a PR.
Is there a new endpoint? Thanks!
An idea, if the second argument passed is a string instead of an object then it should be interpreted as
{xmlns: arguments[1]}
What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.