aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--lib/webcals/xhr.js10
-rw-r--r--package.json3
-rw-r--r--webcals.js149
4 files changed, 158 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index f85fc11..cd03616 100644
--- a/Makefile
+++ b/Makefile
@@ -20,6 +20,7 @@ package: test-agent-config
cat $(VENDOR)/sax.js >> $(WEB_FILE)
echo ';' >> $(WEB_FILE)
cat $(LIB_ROOT)/webcals.js >> $(WEB_FILE)
+ cat $(LIB_ROOT)/ical.js >> $(WEB_FILE)
cat $(LIB_ROOT)/responder.js >> $(WEB_FILE)
cat $(LIB_ROOT)/sax.js >> $(WEB_FILE)
cat $(LIB_ROOT)/template.js >> $(WEB_FILE)
diff --git a/lib/webcals/xhr.js b/lib/webcals/xhr.js
index a8d8d58..fb925f0 100644
--- a/lib/webcals/xhr.js
+++ b/lib/webcals/xhr.js
@@ -52,7 +52,7 @@
url: null,
headers: {},
- data: {},
+ data: null,
_seralize: function _seralize() {
return this.data;
@@ -80,7 +80,12 @@
}
xhr = this.xhr = new this.xhrClass();
- xhr.open(this.method, this.url, this.async, this.user, this.password);
+
+ if (Xhr.authHack) {
+ xhr.open(this.method, this.url, this.async);
+ } else {
+ xhr.open(this.method, this.url, this.async, this.user, this.password);
+ }
for (header in this.headers) {
if (this.headers.hasOwnProperty(header)) {
@@ -88,6 +93,7 @@
}
}
+
xhr.onreadystatechange = function onReadyStateChange() {
var data;
if (xhr.readyState === 4) {
diff --git a/package.json b/package.json
index 947171c..16d6c31 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,8 @@
"devDependencies": {
"mocha": "~1.1",
"chai": "~1.0",
- "test-agent": "~0.6"
+ "test-agent": "~0.6",
+ "http-proxy": "~0.8"
},
"license": "MIT",
"engine": {
diff --git a/webcals.js b/webcals.js
index 082fe0f..48e2a2f 100644
--- a/webcals.js
+++ b/webcals.js
@@ -1107,6 +1107,145 @@ function write (chunk) {
module
));
+(function(module, ns) {
+ // Credit: Andreas Gal - I removed the callback / xhr logic
+
+ // Iterate over all entries if x is an array, otherwise just call fn on x.
+
+ /* Pattern for an individual entry: name:value */
+ var ENTRY = /^([A-Za-z0-9-]+)((?:;[A-Za-z0-9-]+=(?:"[^"]+"|[^";:,]+)(?:,(?:"[^"]+"|[^";:,]+))*)*):(.*)$/;
+
+ /* Pattern for an individual parameter: name=value[,value] */
+ var PARAM = /;([A-Za-z0-9-]+)=((?:"[^"]+"|[^";:,]+)(?:,(?:"[^"]+"|[^";:,]+))*)/g;
+
+ /* Pattern for an individual parameter value: value | "value" */
+ var PARAM_VALUE = /,?("[^"]+"|[^";:,]+)/g;
+
+ // Parse a calendar in iCal format.
+ function ParseICal(text) {
+ // Parse the text into an object graph
+ var lines = text.replace(/\r/g, '').split('\n');
+ var tos = Object.create(null);
+ var stack = [tos];
+
+ // Parse parameters for an entry. Foramt: <param>=<pvalue>[;...]
+ function parseParams(params) {
+ var map = Object.create(null);
+ var param = PARAM.exec(params);
+ while (param) {
+ var values = [];
+ var value = PARAM_VALUE.exec(param[2]);
+ while (value) {
+ values.push(value[1].replace(/^"(.*)"$/, '$1'));
+ value = PARAM_VALUE.exec(param[2]);
+ }
+ map[param[1].toLowerCase()] = (values.length > 1 ? values : values[0]);
+ param = PARAM.exec(params);
+ }
+ return map;
+ }
+
+ // Add a property to the current object. If a property with the same name
+ // already exists, turn it into an array.
+ function add(prop, value, params) {
+ if (params)
+ value = { parameters: parseParams(params), value: value };
+ if (prop in tos) {
+ var previous = tos[prop];
+ if (previous instanceof Array) {
+ previous.push(value);
+ return;
+ }
+ value = [previous, value];
+ }
+ tos[prop] = value;
+ }
+
+ for (var n = 0; n < lines.length; ++n) {
+ var line = lines[n];
+ // check whether the line continues (next line stats with space or tab)
+ var nextLine;
+ while ((nextLine = lines[n+1]) && (nextLine[0] === ' ' || nextLine[0] === '\t')) {
+ line += nextLine.substr(1);
+ ++n;
+ continue;
+ }
+ // parse the entry, format is 'PROPERTY:VALUE'
+ var matches = ENTRY.exec(line);
+
+ if (!matches) {
+ throw new Error('invalid format');
+ }
+
+ var prop = matches[1].toLowerCase();
+ var params = matches[2];
+ var value = matches[3];
+ switch (prop) {
+ case 'begin':
+ var obj = Object.create(null);
+ add(value.toLowerCase(), obj);
+ stack.push(tos = obj);
+ break;
+ case 'end':
+ stack.pop();
+ tos = stack[stack.length - 1];
+ if (stack.length == 1) {
+ var cal = stack[0];
+ if (typeof cal.vcalendar !== 'object' || cal.vcalendar instanceof Array) {
+ throw new Error('single vcalendar object expected');
+ }
+
+ return cal.vcalendar;
+ }
+ break;
+ default:
+ add(prop, value, params);
+ break;
+ }
+ }
+ throw new Error('unexpected end of file');
+ }
+
+ function Value(v) {
+ return (typeof v !== 'object') ? v : v.value;
+ }
+
+ function Parameter(v, name) {
+ if (typeof v !== 'object')
+ return undefined;
+ return v.parameters[name];
+ }
+
+ // Parse a time specification.
+ function ParseDateTime(v) {
+ var dt = Value(v);
+ if (Parameter(v, 'VALUE') === 'DATE') {
+ // 20081202
+ return new Date(dt.substr(0, 4), dt.substr(4, 2), dt.substr(6, 2));
+ }
+ v = Value(v);
+ // 20120426T130000Z
+ var year = dt.substr(0, 4);
+ var month = dt.substr(4, 2) - 1;
+ var day = dt.substr(6, 2);
+ var hour = dt.substr(9, 2);
+ var min = dt.substr(11, 2);
+ var sec = dt.substr(13, 2);
+ if (dt[15] == 'Z') {
+ return new Date(Date.UTC(year, month, day, hour, min, sec));
+ }
+ return new Date(year, month, day, hour, min, sec);
+ }
+
+ module.exports = ParseICal;
+
+}.apply(
+ this,
+ (this.Webcals) ?
+ [Webcals('ical'), Webcals] :
+ [module, require('./webcals')]
+));
+
/**
@namespace
*/
@@ -1710,7 +1849,7 @@ function write (chunk) {
url: null,
headers: {},
- data: {},
+ data: null,
_seralize: function _seralize() {
return this.data;
@@ -1738,7 +1877,12 @@ function write (chunk) {
}
xhr = this.xhr = new this.xhrClass();
- xhr.open(this.method, this.url, this.async, this.user, this.password);
+
+ if (Xhr.authHack) {
+ xhr.open(this.method, this.url, this.async);
+ } else {
+ xhr.open(this.method, this.url, this.async, this.user, this.password);
+ }
for (header in this.headers) {
if (this.headers.hasOwnProperty(header)) {
@@ -1746,6 +1890,7 @@ function write (chunk) {
}
}
+
xhr.onreadystatechange = function onReadyStateChange() {
var data;
if (xhr.readyState === 4) {