iedavclient.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright (c) 2015
  3. *
  4. * This file is licensed under the Affero General Public License version 3
  5. * or later.
  6. *
  7. * See the COPYING-README file.
  8. *
  9. */
  10. /* global dav */
  11. (function(dav) {
  12. /**
  13. * Override davclient.js methods with IE-compatible logic
  14. */
  15. dav.Client.prototype = _.extend({}, dav.Client.prototype, {
  16. /**
  17. * Performs a HTTP request, and returns a Promise
  18. *
  19. * @param {string} method HTTP method
  20. * @param {string} url Relative or absolute url
  21. * @param {Object} headers HTTP headers as an object.
  22. * @param {string} body HTTP request body.
  23. * @return {Promise}
  24. */
  25. request : function(method, url, headers, body) {
  26. var self = this;
  27. var xhr = this.xhrProvider();
  28. headers = headers || {};
  29. if (this.userName) {
  30. headers.Authorization = 'Basic ' + btoa(this.userName + ':' + this.password);
  31. // xhr.open(method, this.resolveUrl(url), true, this.userName, this.password);
  32. }
  33. xhr.open(method, this.resolveUrl(url), true);
  34. var ii;
  35. for(ii in headers) {
  36. xhr.setRequestHeader(ii, headers[ii]);
  37. }
  38. if (body === undefined) {
  39. xhr.send();
  40. } else {
  41. xhr.send(body);
  42. }
  43. return new Promise(function(fulfill, reject) {
  44. xhr.onreadystatechange = function() {
  45. if (xhr.readyState !== 4) {
  46. return;
  47. }
  48. var resultBody = xhr.response;
  49. if (xhr.status === 207) {
  50. resultBody = self.parseMultiStatus(xhr.responseXML);
  51. }
  52. fulfill({
  53. body: resultBody,
  54. status: xhr.status,
  55. xhr: xhr
  56. });
  57. };
  58. xhr.ontimeout = function() {
  59. reject(new Error('Timeout exceeded'));
  60. };
  61. });
  62. },
  63. _getElementsByTagName: function(node, name, resolver) {
  64. var parts = name.split(':');
  65. var tagName = parts[1];
  66. var namespace = resolver(parts[0]);
  67. // make sure we can get elements
  68. if (typeof node === 'string') {
  69. var parser = new DOMParser()
  70. node = parser.parseFromString(node, 'text/xml')
  71. }
  72. if (node.getElementsByTagNameNS) {
  73. return node.getElementsByTagNameNS(namespace, tagName);
  74. }
  75. return node.getElementsByTagName(name);
  76. },
  77. /**
  78. * Parses a multi-status response body.
  79. *
  80. * @param {string} xmlBody
  81. * @param {Array}
  82. */
  83. parseMultiStatus : function(doc) {
  84. var result = [];
  85. var resolver = function(foo) {
  86. var ii;
  87. for(ii in this.xmlNamespaces) {
  88. if (this.xmlNamespaces[ii] === foo) {
  89. return ii;
  90. }
  91. }
  92. }.bind(this);
  93. var responses = this._getElementsByTagName(doc, 'd:response', resolver);
  94. var i;
  95. for (i = 0; i < responses.length; i++) {
  96. var responseNode = responses[i];
  97. var response = {
  98. href : null,
  99. propStat : []
  100. };
  101. var hrefNode = this._getElementsByTagName(responseNode, 'd:href', resolver)[0];
  102. response.href = hrefNode.textContent || hrefNode.text;
  103. var propStatNodes = this._getElementsByTagName(responseNode, 'd:propstat', resolver);
  104. var j = 0;
  105. for (j = 0; j < propStatNodes.length; j++) {
  106. var propStatNode = propStatNodes[j];
  107. var statusNode = this._getElementsByTagName(propStatNode, 'd:status', resolver)[0];
  108. var propStat = {
  109. status : statusNode.textContent || statusNode.text,
  110. properties : []
  111. };
  112. var propNode = this._getElementsByTagName(propStatNode, 'd:prop', resolver)[0];
  113. if (!propNode) {
  114. continue;
  115. }
  116. var k = 0;
  117. for (k = 0; k < propNode.childNodes.length; k++) {
  118. var prop = propNode.childNodes[k];
  119. var value = this._parsePropNode(prop);
  120. propStat.properties['{' + prop.namespaceURI + '}' + (prop.localName || prop.baseName)] = value;
  121. }
  122. response.propStat.push(propStat);
  123. }
  124. result.push(response);
  125. }
  126. return result;
  127. }
  128. });
  129. })(dav);