util.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. if (!dojo._hasResource["dojox.wire.ml.util"]) { // _hasResource checks added by
  2. // build. Do not use
  3. // _hasResource directly in your
  4. // code.
  5. dojo._hasResource["dojox.wire.ml.util"] = true;
  6. dojo.provide("dojox.wire.ml.util");
  7. dojo.require("dojox.data.dom");
  8. dojo.require("dojox.wire.Wire");
  9. dojox.wire.ml._getValue = function(/* String */source, /* Array */args) {
  10. // summary:
  11. // Return a value
  12. // description:
  13. // This method obtains an object by an ID of a widget or an DOM
  14. // element.
  15. // If 'source' specifies a dotted notation to its property, a Wire is
  16. // used to get the object property.
  17. // If 'source' starts with "arguments", 'args' is used as a root
  18. // object for the Wire.
  19. // source:
  20. // A string to specify an object and its property
  21. // args:
  22. // An optional arguments array
  23. // returns:
  24. // A value
  25. if (!source) {
  26. return undefined; // undefined
  27. }
  28. var property = undefined;
  29. if (args && source.length >= 9 && source.substring(0, 9) == "arguments") {
  30. property = source.substring(9);
  31. return new dojox.wire.Wire({
  32. property : property
  33. }).getValue(args);
  34. }
  35. var i = source.indexOf('.');
  36. if (i >= 0) {
  37. property = source.substring(i + 1);
  38. source = source.substring(0, i);
  39. }
  40. var object = (dijit.byId(source) || dojo.byId(source) || dojo
  41. .getObject(source));
  42. if (!object) {
  43. return undefined; // undefined
  44. }
  45. if (!property) {
  46. return object; // Object
  47. } else {
  48. return new dojox.wire.Wire({
  49. object : object,
  50. property : property
  51. }).getValue(); // anything
  52. }
  53. };
  54. dojox.wire.ml._setValue = function(/* String */target, /* anything */value) {
  55. // summary:
  56. // Store a value
  57. // description:
  58. // This method stores a value by an ID of a widget or an DOM
  59. // element with a dotted notation to its property, using a Wire.
  60. // target:
  61. // A string to specify an object and its property
  62. // value:
  63. // A value
  64. if (!target) {
  65. return; // undefined
  66. }
  67. var i = target.indexOf('.');
  68. if (i < 0) {
  69. return; // undefined
  70. }
  71. var object = this._getValue(target.substring(0, i));
  72. if (!object) {
  73. return; // undefined
  74. }
  75. var property = target.substring(i + 1);
  76. new dojox.wire.Wire({
  77. object : object,
  78. property : property
  79. }).setValue(value);
  80. };
  81. dojo.declare("dojox.wire.ml.XmlElement", null, {
  82. // summary:
  83. // An object wrapping an XML element
  84. // description:
  85. // This class represents an XML element.
  86. constructor : function(/* Element||String */element) {
  87. // summary:
  88. // Initialize with an XML element or a tag name
  89. // element:
  90. // An XML element or a tag name
  91. if (dojo.isString(element)) {
  92. element = this._getDocument().createElement(element);
  93. }
  94. this.element = element;
  95. },
  96. getPropertyValue : function(/* String */property) {
  97. // summary:
  98. // Return a property value
  99. // description:
  100. // If 'property' starts with '@', the attribute value is returned.
  101. // If 'property' specifies "text()", the value of the first child
  102. // text is returned.
  103. // Otherwise, child elements of the tag name specified with
  104. // 'property' are returned.
  105. // property:
  106. // A property name
  107. // returns:
  108. // A property value
  109. var value = undefined;
  110. if (!this.element) {
  111. return value; // undefined
  112. }
  113. if (!property) {
  114. return value; // undefined
  115. }
  116. if (property.charAt(0) == '@') {
  117. var attribute = property.substring(1);
  118. value = this.element.getAttribute(attribute);
  119. } else if (property == "text()") {
  120. var text = this.element.firstChild;
  121. if (text) {
  122. value = text.nodeValue;
  123. }
  124. } else { // child elements
  125. var elements = [];
  126. for (var i = 0; i < this.element.childNodes.length; i++) {
  127. var child = this.element.childNodes[i];
  128. if (child.nodeType === 1 /* ELEMENT_NODE */
  129. && child.nodeName == property) {
  130. elements.push(new dojox.wire.ml.XmlElement(child));
  131. }
  132. }
  133. if (elements.length > 0) {
  134. if (elements.length === 1) {
  135. value = elements[0];
  136. } else {
  137. value = elements;
  138. }
  139. }
  140. }
  141. return value; // String||Array||XmlElement
  142. },
  143. setPropertyValue : function(/* String */property, /* String||Array||XmlElement */
  144. value) {
  145. // summary:
  146. // Store a property value
  147. // description:
  148. // If 'property' starts with '@', 'value' is set to the attribute.
  149. // If 'property' specifies "text()", 'value' is set as the first
  150. // child text.
  151. // If 'value' is a string, a child element of the tag name
  152. // specified with 'property' is created and 'value' is set as
  153. // the first child text of the child element.
  154. // Otherwise, 'value' is set to as child elements.
  155. // property:
  156. // A property name
  157. // value:
  158. // A property value
  159. if (!this.element) {
  160. return; // undefined
  161. }
  162. if (!property) {
  163. return; // undefined
  164. }
  165. if (property.charAt(0) == '@') {
  166. var attribute = property.substring(1);
  167. if (value) {
  168. this.element.setAttribute(attribute, value);
  169. } else {
  170. this.element.removeAttribute(attribute);
  171. }
  172. } else if (property == "text()") {
  173. while (this.element.firstChild) {
  174. this.element.removeChild(this.element.firstChild);
  175. }
  176. if (value) {
  177. var text = this._getDocument().createTextNode(value);
  178. this.element.appendChild(text);
  179. }
  180. } else { // child elements
  181. var nextChild = null;
  182. for (var i = this.element.childNodes.length - 1; i >= 0; i--) {
  183. var child = this.element.childNodes[i];
  184. if (child.nodeType === 1 /* ELEMENT_NODE */
  185. && child.nodeName == property) {
  186. if (!nextChild) {
  187. nextChild = child.nextSibling;
  188. }
  189. this.element.removeChild(child);
  190. }
  191. }
  192. if (value) {
  193. if (dojo.isArray(value)) {
  194. for (var i in value) {
  195. var e = value[i];
  196. if (e.element) {
  197. this.element.insertBefore(e.element, nextChild);
  198. }
  199. }
  200. } else if (value instanceof dojox.wire.ml.XmlElement) {
  201. if (value.element) {
  202. this.element.insertBefore(value.element, nextChild);
  203. }
  204. } else { // assume string
  205. var child = this._getDocument().createElement(property);
  206. var text = this._getDocument().createTextNode(value);
  207. child.appendChild(text);
  208. this.element.insertBefore(child, nextChild);
  209. }
  210. }
  211. }
  212. },
  213. toString : function() {
  214. // summary:
  215. // Return a value of the first text child of the element
  216. // description:
  217. // A value of the first text child of the element is returned.
  218. // returns:
  219. // A value of the first text child of the element
  220. var s = "";
  221. if (this.element) {
  222. var text = this.element.firstChild;
  223. if (text) {
  224. s = text.nodeValue;
  225. }
  226. }
  227. return s; // String
  228. },
  229. toObject : function() {
  230. // summary:
  231. // Return an object representation of the element
  232. // description:
  233. // An object with properties for child elements, attributes and
  234. // text is returned.
  235. // returns:
  236. // An object representation of the element
  237. if (!this.element) {
  238. return null; // null
  239. }
  240. var text = "";
  241. var obj = {};
  242. var elements = 0;
  243. for (var i = 0; i < this.element.childNodes.length; i++) {
  244. var child = this.element.childNodes[i];
  245. if (child.nodeType === 1 /* ELEMENT_NODE */) {
  246. elements++;
  247. var o = new dojox.wire.ml.XmlElement(child).toObject();
  248. var name = child.nodeName;
  249. var p = obj[name];
  250. if (!p) {
  251. obj[name] = o;
  252. } else if (dojo.isArray(p)) {
  253. p.push(o);
  254. } else {
  255. obj[name] = [p, o]; // make them array
  256. }
  257. } else if (child.nodeType === 3 /* TEXT_NODE */
  258. || child.nodeType === 4 /* CDATA_SECTION_NODE */) {
  259. text += child.nodeValue;
  260. }
  261. }
  262. var attributes = 0;
  263. if (this.element.nodeType === 1 /* ELEMENT_NODE */) {
  264. attributes = this.element.attributes.length;
  265. for (var i = 0; i < attributes; i++) {
  266. var attr = this.element.attributes[i];
  267. obj["@" + attr.nodeName] = attr.nodeValue;
  268. }
  269. }
  270. if (elements === 0) {
  271. if (attributes === 0) {
  272. // text only
  273. return text; // String
  274. }
  275. // text with attributes
  276. obj["text()"] = text;
  277. }
  278. // else ignore text
  279. return obj; // Object
  280. },
  281. _getDocument : function() {
  282. // summary:
  283. // Return a DOM document
  284. // description:
  285. // If 'element' is specified, a DOM document of the element is
  286. // returned.
  287. // Otherwise, a DOM document is created.
  288. // returns:
  289. // A DOM document
  290. if (this.element) {
  291. return (this.element.nodeType == 9
  292. /* DOCUMENT_NODE */ ? this.element
  293. : this.element.ownerDocument); // Document
  294. } else {
  295. return dojox.data.dom.createDocument(); // Document
  296. }
  297. }
  298. });
  299. }