diff options
author | James Lal <james@lightsofapollo.com> | 2012-06-19 22:07:17 -0700 |
---|---|---|
committer | James Lal <james@lightsofapollo.com> | 2012-06-19 22:07:17 -0700 |
commit | 038911be29c875e0fcd24472e815167bb98ce833 (patch) | |
tree | 8d762fb3e0d812aeab6dab262d6f6bd411940344 | |
parent | be947b56151b774d4b555097f2b8a8b4f47b633d (diff) | |
download | jsCalDAV-038911be29c875e0fcd24472e815167bb98ce833.tar.gz |
wip xml parsing
-rw-r--r-- | lib/webcals/sax.js | 18 | ||||
-rw-r--r-- | lib/webcals/sax/dav_response.js | 140 | ||||
-rw-r--r-- | samples/xml/prop-get.xml | 27 | ||||
-rw-r--r-- | test/webcals/sax/dav_response_test.js | 75 | ||||
-rw-r--r-- | test/webcals/sax_test.js | 14 |
5 files changed, 236 insertions, 38 deletions
diff --git a/lib/webcals/sax.js b/lib/webcals/sax.js index 9cc8425..d6f7592 100644 --- a/lib/webcals/sax.js +++ b/lib/webcals/sax.js @@ -131,23 +131,26 @@ }, _fireHandler: function(event, data) { - if (event in this.handler) { + if (typeof(this.handler[event]) === 'function') { this.handler[event].call(this, data, this.handler); } }, onopentag: function(data) { var handle; - var stackData = {}; + var stackData = { + local: data.local, + name: data.name + }; //build tagSpec for others to use. data.tagSpec = data.uri + '/' + data.local; //add to stackData - stackData.tag = data.tagSpec; + stackData.tagSpec = data.tagSpec; // shortcut to the current tag object - this.currentTag = data; + this.currentTag = stackData; //determine if we need to switch to another //handler object. @@ -163,10 +166,15 @@ this._fireHandler('onopentag', data); }, + //XXX: optimize later + get currentTag() { + return this.tagStack[this.tagStack.length - 1]; + }, + onclosetag: function(data) { var stack, handler; - stack = this.tagStack[this.tagStack.length - 1]; + stack = this.currentTag; if (stack.handler) { //fire oncomplete handler if available diff --git a/lib/webcals/sax/dav_response.js b/lib/webcals/sax/dav_response.js new file mode 100644 index 0000000..5b3e0b7 --- /dev/null +++ b/lib/webcals/sax/dav_response.js @@ -0,0 +1,140 @@ +(function(module, ns) { + + var HTTP_STATUS = /([0-9]{3,3})/; + + var Base = ns.require('sax/base'); + + var TextHandler = Base.create({ + name: 'text', + + //don't add text only elements + //to the stack as objects + onopentag: null, + onclosetag: null, + + //add the value to the parent + //value where key is local tag name + //and value is the text. + ontext: function(data) { + var handler = this.handler; + this.current[this.currentTag[handler.tagField]] = data; + } + }); + + var HttpStatusHandler = TextHandler.create({ + name: 'status', + + ontext: function(data, handler) { + var match = data.match(HTTP_STATUS); + + if (match) { + var handler = this.handler; + this.current[this.currentTag[handler.tagField]] = match[1]; + } else { + this._super.ontext.call(this, data, handler); + } + } + }); + + var ArrayHandler = Base.create({ + name: 'array', + + handles: { + 'DAV:/href': TextHandler + }, + + onopentag: function(data, handler) { + var last; + var tag = data[handler.tagField]; + var last = this.tagStack[this.tagStack.length - 1]; + + if (last.handler === handler) { + this.stack.push(this.current); + this.current = this.current[tag] = []; + } else { + this.current.push(tag); + } + }, + + ontext: null, + onclosetag: null, + + oncomplete: function() { + this.current = this.stack.pop(); + } + + }); + + var PropStatHandler = Base.create({ + name: 'propstat', + + handles: { + 'DAV:/href': TextHandler, + 'DAV:/status': HttpStatusHandler, + 'DAV:/resourcetype': ArrayHandler + }, + + onopentag: function(data, handler) { + //orphan + if (data.tagSpec === 'DAV:/propstat') { + this.stack.push(this.current); + return this.current = {}; + } + + handler._super.onopentag.call(this, data, handler); + }, + + oncomplete: function() { + var parent = this.stack[this.stack.length - 1]; + var key; + + //console.log(this.current); + + for (key in this.current.prop) { + if (this.current.prop.hasOwnProperty(key)) { + parent[key] = { + status: this.current.status, + value: this.current.prop[key] + } + } + } + }, + + }); + + var Response = Base.create({ + name: 'dav_response', + handles: { + 'DAV:/href': TextHandler, + 'DAV:/propstat': PropStatHandler + }, + + //onopentag: function(data, handler) { + //if (data.tagSpec === 'DAV:/response') { + //this.stack.push(this.current); + //return this.current = {}; + //} + + //handler._super.onopentag.call(this, data, handler._super); + //}, + + //oncomplete: function() { + //var parent; + + //if (this.current.href) { + //parent = this.stack[this.stack.length - 1]; + //parent[this.current.href] = this.current.propstat; + //} + //} + + }); + + module.exports = Response; + +}.apply( + this, + (this.Webcals) ? + [Webcals('sax/dav_response'), Webcals] : + [module, require('../webcals')] +)); + diff --git a/samples/xml/prop-get.xml b/samples/xml/prop-get.xml deleted file mode 100644 index 72ee984..0000000 --- a/samples/xml/prop-get.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<D:multistatus xmlns:D="DAV:"> - - <D:response> - <D:href>/calendar/dav/calmozilla1%40gmail.com/user/</D:href> - <D:propstat> - <D:status>HTTP/1.1 200 OK</D:status> - <D:prop> - <D:principal-URL> - <D:href>/calendar/dav/calmozilla1@gmail.com/user/</D:href> - </D:principal-URL> - <D:resourcetype> - <D:principal /> - <D:collection /> - </D:resourcetype> - </D:prop> - </D:propstat> - - <D:propstat> - <D:status>HTTP/1.1 404 Not Found</D:status> - <D:prop> - <A:current-user-principal xmlns:A="DAV:" /> - </D:prop> - </D:propstat> - </D:response> - -</D:multistatus> diff --git a/test/webcals/sax/dav_response_test.js b/test/webcals/sax/dav_response_test.js new file mode 100644 index 0000000..8e84e6b --- /dev/null +++ b/test/webcals/sax/dav_response_test.js @@ -0,0 +1,75 @@ +requireLib('sax'); +requireLib('sax/base'); +requireLib('sax/dav_response'); + +suite('webcals/sax/base', function() { + + var data, + subject, + parser, + Parse, + Response, + Base, + handler; + + + suiteSetup(function() { + Parse = Webcals.require('sax'); + Base = Webcals.require('sax/base'); + Response = Webcals.require('sax/dav_response'); + }); + + setup(function() { + //we omit the option to pass base parser + //because we are the base parser + subject = new Parse(); + subject.registerHandler('DAV:/response', Response); + }); + + suite('parsing', function() { + var xml; + + defineSample('xml/propget.xml', function(data) { + xml = data; + }); + + expected = { + '/calendar/user': { + + 'principal-URL': { + status: '200', + value: '/calendar/user/' + }, + + resourcetype: { + status: '200', + value: [ + 'principal', + 'collection' + ] + } + }, + + '/calendar/other': { + missing: { + status: '200', + value: {} + } + } + }; + + test('output', function(done) { + subject.once('complete', function(data) { + console.log(JSON.stringify(data)); + //assert.deepEqual( + //data, expected, + //"expected \n '" + JSON.stringify(data) + "'\n to equal \n '" + + //JSON.stringify(expected) + '\n"' + //); + done(); + }); + subject.write(xml).close(); + }); + }); + +}); diff --git a/test/webcals/sax_test.js b/test/webcals/sax_test.js index 18a18a0..f9479e6 100644 --- a/test/webcals/sax_test.js +++ b/test/webcals/sax_test.js @@ -169,15 +169,16 @@ suite('webcals/sax', function() { test('basic event', function() { var obj = { local: 'foo', - uri: 'bar' + uri: 'bar', + name: 'foo' }; subject.onopentag(obj); - assert.equal(subject.currentTag, obj); assert.equal(obj.tagSpec, 'bar/foo'); assert.deepEqual( - subject.tagStack, - [{ tag: 'bar/foo' }] + subject.tagStack[0].tagSpec, + 'bar/foo', + 'works' ); firesHandler('opentag', obj); @@ -192,7 +193,8 @@ suite('webcals/sax', function() { subject.registerHandler('a/a', newHandler); subject.onopentag({ local: 'a', - uri: 'a' + uri: 'a', + name: 'a' }); }); @@ -200,7 +202,7 @@ suite('webcals/sax', function() { assert.equal(subject.handler, newHandler); assert.deepEqual( subject.tagStack, [ - { tag: 'a/a', handler: newHandler } + { tagSpec: 'a/a', local: 'a', name: 'a', handler: newHandler } ] ); }); |