model.js 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306
  1. define("dojox/atom/io/model", [
  2. "dojo/_base/kernel",
  3. "dojo/_base/declare", // dojo.declare
  4. "dojo/_base/lang",
  5. "dojo/date/stamp",
  6. "dojox/xml/parser"
  7. ], function (dojo, declare, lang, stamp, parser) {
  8. var model = dojo.getObject("dojox.atom.io.model", true);
  9. model._Constants = {
  10. // summary:
  11. // Container for general constants.
  12. // description:
  13. // Container for general constants.
  14. "ATOM_URI": "http://www.w3.org/2005/Atom",
  15. "ATOM_NS": "http://www.w3.org/2005/Atom",
  16. "PURL_NS": "http://purl.org/atom/app#",
  17. "APP_NS": "http://www.w3.org/2007/app"
  18. };
  19. model._actions = {
  20. // summary:
  21. // Container for tag handling functions.
  22. // description:
  23. // Container for tag handling functions. Each child of this container is
  24. // a handler function for the given type of node. Each accepts two parameters:
  25. // obj: Object.
  26. // The object to insert data into.
  27. // node: DOM Node.
  28. // The dom node containing the data
  29. "link": function(obj,node){
  30. if(obj.links === null){obj.links = [];}
  31. var link = new model.Link();
  32. link.buildFromDom(node);
  33. obj.links.push(link);
  34. },
  35. "author": function(obj,node){
  36. if(obj.authors === null){obj.authors = [];}
  37. var person = new model.Person("author");
  38. person.buildFromDom(node);
  39. obj.authors.push(person);
  40. },
  41. "contributor": function(obj,node){
  42. if(obj.contributors === null){obj.contributors = [];}
  43. var person = new model.Person("contributor");
  44. person.buildFromDom(node);
  45. obj.contributors.push(person);
  46. },
  47. "category": function(obj,node){
  48. if(obj.categories === null){obj.categories = [];}
  49. var cat = new model.Category();
  50. cat.buildFromDom(node);
  51. obj.categories.push(cat);
  52. },
  53. "icon": function(obj,node){
  54. obj.icon = parser.textContent(node);
  55. },
  56. "id": function(obj,node){
  57. obj.id = parser.textContent(node);
  58. },
  59. "rights": function(obj,node){
  60. obj.rights = parser.textContent(node);
  61. },
  62. "subtitle": function(obj,node){
  63. var cnt = new model.Content("subtitle");
  64. cnt.buildFromDom(node);
  65. obj.subtitle = cnt;
  66. },
  67. "title": function(obj,node){
  68. var cnt = new model.Content("title");
  69. cnt.buildFromDom(node);
  70. obj.title = cnt;
  71. },
  72. "updated": function(obj,node){
  73. obj.updated = model.util.createDate(node);
  74. },
  75. // Google news
  76. "issued": function(obj,node){
  77. obj.issued = model.util.createDate(node);
  78. },
  79. // Google news
  80. "modified": function(obj,node){
  81. obj.modified = model.util.createDate(node);
  82. },
  83. "published": function(obj,node){
  84. obj.published = model.util.createDate(node);
  85. },
  86. "entry": function(obj,node){
  87. if(obj.entries === null){obj.entries = [];}
  88. //The object passed in should be a Feed object, since only feeds can contain Entries
  89. var entry = obj.createEntry ? obj.createEntry() : new model.Entry();
  90. entry.buildFromDom(node);
  91. obj.entries.push(entry);
  92. },
  93. "content": function(obj, node){
  94. var cnt = new model.Content("content");
  95. cnt.buildFromDom(node);
  96. obj.content = cnt;
  97. },
  98. "summary": function(obj, node){
  99. var summary = new model.Content("summary");
  100. summary.buildFromDom(node);
  101. obj.summary = summary;
  102. },
  103. "name": function(obj,node){
  104. obj.name = parser.textContent(node);
  105. },
  106. "email" : function(obj,node){
  107. obj.email = parser.textContent(node);
  108. },
  109. "uri" : function(obj,node){
  110. obj.uri = parser.textContent(node);
  111. },
  112. "generator" : function(obj,node){
  113. obj.generator = new model.Generator();
  114. obj.generator.buildFromDom(node);
  115. }
  116. };
  117. model.util = {
  118. createDate: function(/*DOM node*/node){
  119. // summary:
  120. // Utility function to create a date from a DOM node's text content.
  121. // description:
  122. // Utility function to create a date from a DOM node's text content.
  123. //
  124. // node:
  125. // The DOM node to inspect.
  126. // returns:
  127. // Date object from a DOM Node containing a ISO-8610 string.
  128. var textContent = parser.textContent(node);
  129. if(textContent){
  130. return stamp.fromISOString(lang.trim(textContent));
  131. }
  132. return null;
  133. },
  134. escapeHtml: function(/*String*/str){
  135. // summary:
  136. // Utility function to escape XML special characters in an HTML string.
  137. // description:
  138. // Utility function to escape XML special characters in an HTML string.
  139. //
  140. // str:
  141. // The string to escape
  142. // returns:
  143. // HTML String with special characters (<,>,&, ", etc,) escaped.
  144. return str.replace(/&/gm, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;")
  145. .replace(/'/gm, "&#39;"); // String
  146. },
  147. unEscapeHtml: function(/*String*/str){
  148. // summary:
  149. // Utility function to un-escape XML special characters in an HTML string.
  150. // description:
  151. // Utility function to un-escape XML special characters in an HTML string.
  152. //
  153. // str:
  154. // The string to un-escape.
  155. // returns:
  156. // HTML String converted back to the normal text (unescaped) characters (<,>,&, ", etc,).
  157. return str.replace(/&lt;/gm, "<").replace(/&gt;/gm, ">").replace(/&quot;/gm, "\"")
  158. .replace(/&#39;/gm, "'").replace(/&amp;/gm, "&"); // String
  159. },
  160. getNodename: function(/*DOM node*/node){
  161. // summary:
  162. // Utility function to get a node name and deal with IE's bad handling of namespaces
  163. // on tag names.
  164. // description:
  165. // Utility function to get a node name and deal with IE's bad handling of namespaces
  166. // on tag names.
  167. //
  168. // node:
  169. // The DOM node whose name to retrieve.
  170. // returns:
  171. // String
  172. // The name without namespace prefixes.
  173. var name = null;
  174. if(node !== null){
  175. name = node.localName ? node.localName: node.nodeName;
  176. if(name !== null){
  177. var nsSep = name.indexOf(":");
  178. if(nsSep !== -1){
  179. name = name.substring((nsSep + 1), name.length);
  180. }
  181. }
  182. }
  183. return name;
  184. }
  185. };
  186. model.Node = dojo.declare(/*===== 'dojox.atom.io.model.Node', =====*/ null, {
  187. constructor: function(name_space,name, attributes,content, shortNs){
  188. this.name_space = name_space;
  189. this.name = name;
  190. this.attributes = [];
  191. if(attributes){
  192. this.attributes = attributes;
  193. }
  194. this.content = [];
  195. this.rawNodes = [];
  196. this.textContent = null;
  197. if(content){
  198. this.content.push(content);
  199. }
  200. this.shortNs = shortNs;
  201. this._objName = "Node";//for debugging purposes
  202. this.nodeType = "Node";
  203. },
  204. buildFromDom: function(node){
  205. this._saveAttributes(node);
  206. this.name_space = node.namespaceURI;
  207. this.shortNs = node.prefix;
  208. this.name = model.util.getNodename(node);
  209. for(var x=0; x < node.childNodes.length; x++){
  210. var c = node.childNodes[x];
  211. if(model.util.getNodename(c) != "#text" ){
  212. this.rawNodes.push(c);
  213. var n = new model.Node();
  214. n.buildFromDom(c, true);
  215. this.content.push(n);
  216. }else{
  217. this.content.push(c.nodeValue);
  218. }
  219. }
  220. this.textContent = parser.textContent(node);
  221. },
  222. _saveAttributes: function(node){
  223. if(!this.attributes){this.attributes = [];}
  224. // Work around lack of hasAttributes() in IE
  225. var hasAttributes = function(node){
  226. var attrs = node.attributes;
  227. if(attrs === null){return false;}
  228. return (attrs.length !== 0);
  229. };
  230. if(hasAttributes(node) && this._getAttributeNames){
  231. var names = this._getAttributeNames(node);
  232. if(names && names.length > 0){
  233. for(var x in names){
  234. var attrib = node.getAttribute(names[x]);
  235. if(attrib){this.attributes[names[x]] = attrib;}
  236. }
  237. }
  238. }
  239. },
  240. addAttribute: function(name, value){
  241. this.attributes[name]=value;
  242. },
  243. getAttribute: function(name){
  244. return this.attributes[name];
  245. },
  246. //if child objects want their attributes parsed, they should override
  247. //to return an array of attrib names
  248. _getAttributeNames: function(node){
  249. var names = [];
  250. for(var i =0; i<node.attributes.length; i++){
  251. names.push(node.attributes[i].nodeName);
  252. }
  253. return names;
  254. },
  255. toString: function(){
  256. var xml = [];
  257. var x;
  258. var name = (this.shortNs?this.shortNs+":":'')+this.name;
  259. var cdata = (this.name == "#cdata-section");
  260. if(cdata){
  261. xml.push("<![CDATA[");
  262. xml.push(this.textContent);
  263. xml.push("]]>");
  264. }else{
  265. xml.push("<");
  266. xml.push(name);
  267. if(this.name_space){
  268. xml.push(" xmlns='" + this.name_space + "'");
  269. }
  270. if(this.attributes){
  271. for(x in this.attributes){
  272. xml.push(" " + x + "='" + this.attributes[x] + "'");
  273. }
  274. }
  275. if(this.content){
  276. xml.push(">");
  277. for(x in this.content){
  278. xml.push(this.content[x]);
  279. }
  280. xml.push("</" + name + ">\n");
  281. }else{
  282. xml.push("/>\n");
  283. }
  284. }
  285. return xml.join('');
  286. },
  287. addContent: function(content){
  288. this.content.push(content);
  289. }
  290. });
  291. //Types are as follows: links: array of Link, authors: array of Person, categories: array of Category
  292. //contributors: array of Person, ico
  293. model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ model.Node,{
  294. constructor: function(args){
  295. this.ATOM_URI = model._Constants.ATOM_URI;
  296. this.links = null; //Array of Link
  297. this.authors = null; //Array of Person
  298. this.categories = null; //Array of Category
  299. this.contributors = null; //Array of Person
  300. this.icon = this.id = this.logo = this.xmlBase = this.rights = null; //String
  301. this.subtitle = this.title = null; //Content
  302. this.updated = this.published = null; //Date
  303. // Google news
  304. this.issued = this.modified = null; //Date
  305. this.content = null; //Content
  306. this.extensions = null; //Array of Node, non atom based
  307. this.entries = null; //Array of Entry
  308. this.name_spaces = {};
  309. this._objName = "AtomItem"; //for debugging purposes
  310. this.nodeType = "AtomItem";
  311. },
  312. // summary: Class container for generic Atom items.
  313. // description: Class container for generic Atom items.
  314. _getAttributeNames: function(){return null;},
  315. _accepts: {},
  316. accept: function(tag){return Boolean(this._accepts[tag]);},
  317. _postBuild: function(){},//child objects can override this if they want to be called after a Dom build
  318. buildFromDom: function(node){
  319. var i, c, n;
  320. for(i=0; i<node.attributes.length; i++){
  321. c = node.attributes.item(i);
  322. n = model.util.getNodename(c);
  323. if(c.prefix == "xmlns" && c.prefix != n){
  324. this.addNamespace(c.nodeValue, n);
  325. }
  326. }
  327. c = node.childNodes;
  328. for(i = 0; i< c.length; i++){
  329. if(c[i].nodeType == 1) {
  330. var name = model.util.getNodename(c[i]);
  331. if(!name){continue;}
  332. if(c[i].namespaceURI != model._Constants.ATOM_NS && name != "#text"){
  333. if(!this.extensions){this.extensions = [];}
  334. var extensionNode = new model.Node();
  335. extensionNode.buildFromDom(c[i]);
  336. this.extensions.push(extensionNode);
  337. }
  338. if(!this.accept(name.toLowerCase())){
  339. continue;
  340. }
  341. var fn = model._actions[name];
  342. if(fn) {
  343. fn(this,c[i]);
  344. }
  345. }
  346. }
  347. this._saveAttributes(node);
  348. if(this._postBuild){this._postBuild();}
  349. },
  350. addNamespace: function(fullName, shortName){
  351. if(fullName && shortName){
  352. this.name_spaces[shortName] = fullName;
  353. }
  354. },
  355. addAuthor: function(/*String*/name, /*String*/email, /*String*/uri){
  356. // summary:
  357. // Function to add in an author to the list of authors.
  358. // description:
  359. // Function to add in an author to the list of authors.
  360. //
  361. // name:
  362. // The author's name.
  363. // email:
  364. // The author's e-mail address.
  365. // uri:
  366. // A URI associated with the author.
  367. if(!this.authors){this.authors = [];}
  368. this.authors.push(new model.Person("author",name,email,uri));
  369. },
  370. addContributor: function(/*String*/name, /*String*/email, /*String*/uri){
  371. // summary:
  372. // Function to add in an author to the list of authors.
  373. // description:
  374. // Function to add in an author to the list of authors.
  375. //
  376. // name:
  377. // The author's name.
  378. // email:
  379. // The author's e-mail address.
  380. // uri:
  381. // A URI associated with the author.
  382. if(!this.contributors){this.contributors = [];}
  383. this.contributors.push(new model.Person("contributor",name,email,uri));
  384. },
  385. addLink: function(/*String*/href,/*String*/rel,/*String*/hrefLang,/*String*/title,/*String*/type){
  386. // summary:
  387. // Function to add in a link to the list of links.
  388. // description:
  389. // Function to add in a link to the list of links.
  390. //
  391. // href:
  392. // The href.
  393. // rel:
  394. // String
  395. // hrefLang:
  396. // String
  397. // title:
  398. // A title to associate with the link.
  399. // type:
  400. // The type of link is is.
  401. if(!this.links){this.links=[];}
  402. this.links.push(new model.Link(href,rel,hrefLang,title,type));
  403. },
  404. removeLink: function(/*String*/href, /*String*/rel){
  405. // summary:
  406. // Function to remove a link from the list of links.
  407. // description:
  408. // Function to remove a link from the list of links.
  409. //
  410. // href:
  411. // The href.
  412. // rel:
  413. // String
  414. if(!this.links || !lang.isArray(this.links)){return;}
  415. var count = 0;
  416. for(var i = 0; i < this.links.length; i++){
  417. if((!href || this.links[i].href === href) && (!rel || this.links[i].rel === rel)){
  418. this.links.splice(i,1); count++;
  419. }
  420. }
  421. return count;
  422. },
  423. removeBasicLinks: function(){
  424. // summary:
  425. // Function to remove all basic links from the list of links.
  426. // description:
  427. // Function to remove all basic link from the list of links.
  428. if(!this.links){return;}
  429. var count = 0;
  430. for(var i = 0; i < this.links.length; i++){
  431. if(!this.links[i].rel){this.links.splice(i,1); count++; i--;}
  432. }
  433. return count;
  434. },
  435. addCategory: function(/*String*/scheme, /*String*/term, /*String*/label){
  436. // summary:
  437. // Function to add in a category to the list of categories.
  438. // description:
  439. // Function to add in a category to the list of categories.
  440. //
  441. // scheme:
  442. // String
  443. // term:
  444. // String
  445. // label:
  446. // String
  447. if(!this.categories){this.categories = [];}
  448. this.categories.push(new model.Category(scheme,term,label));
  449. },
  450. getCategories: function(/*String*/scheme){
  451. // summary:
  452. // Function to get all categories that match a particular scheme.
  453. // description:
  454. // Function to get all categories that match a particular scheme.
  455. //
  456. // scheme:
  457. // String
  458. // The scheme to filter on.
  459. if(!scheme){return this.categories;}
  460. //If categories belonging to a particular scheme are required, then create a new array containing these
  461. var arr = [];
  462. for(var x in this.categories){
  463. if(this.categories[x].scheme === scheme){arr.push(this.categories[x]);}
  464. }
  465. return arr;
  466. },
  467. removeCategories: function(/*String*/scheme, /*String*/term){
  468. // summary:
  469. // Function to remove all categories that match a particular scheme and term.
  470. // description:
  471. // Function to remove all categories that match a particular scheme and term.
  472. //
  473. // scheme:
  474. // The scheme to filter on.
  475. // term:
  476. // The term to filter on.
  477. if(!this.categories){return;}
  478. var count = 0;
  479. for(var i=0; i<this.categories.length; i++){
  480. if((!scheme || this.categories[i].scheme === scheme) && (!term || this.categories[i].term === term)){
  481. this.categories.splice(i, 1); count++; i--;
  482. }
  483. }
  484. return count;
  485. },
  486. setTitle: function(/*String*/str, /*String*/type){
  487. // summary:
  488. // Function to set the title of the item.
  489. // description:
  490. // Function to set the title of the item.
  491. //
  492. // str:
  493. // The title to set.
  494. // type:
  495. // The type of title format, text, xml, xhtml, etc.
  496. if(!str){return;}
  497. this.title = new model.Content("title");
  498. this.title.value = str;
  499. if(type){this.title.type = type;}
  500. },
  501. addExtension: function(/*String*/name_space,/*String*/name, /*Array*/attributes, /*String*/content, /*String*/shortNS){
  502. // summary:
  503. // Function to add in an extension namespace into the item.
  504. // description:
  505. // Function to add in an extension namespace into the item.
  506. //
  507. // name_space:
  508. // The namespace of the extension.
  509. // name:
  510. // The name of the extension
  511. // attributes:
  512. // The attributes associated with the extension.
  513. // content:
  514. // The content of the extension.
  515. if(!this.extensions){this.extensions=[];}
  516. this.extensions.push(new model.Node(name_space,name,attributes,content, shortNS || "ns"+this.extensions.length));
  517. },
  518. getExtensions: function(/*String*/name_space, /*String*/name){
  519. // summary:
  520. // Function to get extensions that match a namespace and name.
  521. // description:
  522. // Function to get extensions that match a namespace and name.
  523. //
  524. // name_space:
  525. // The namespace of the extension.
  526. // name:
  527. // The name of the extension
  528. var arr = [];
  529. if(!this.extensions){return arr;}
  530. for(var x in this.extensions){
  531. if((this.extensions[x].name_space === name_space || this.extensions[x].shortNs === name_space) && (!name || this.extensions[x].name === name)){
  532. arr.push(this.extensions[x]);
  533. }
  534. }
  535. return arr;
  536. },
  537. removeExtensions: function(/*String*/name_space, /*String*/name){
  538. // summary:
  539. // Function to remove extensions that match a namespace and name.
  540. // description:
  541. // Function to remove extensions that match a namespace and name.
  542. //
  543. // name_space:
  544. // The namespace of the extension.
  545. // name:
  546. // The name of the extension
  547. if(!this.extensions){return;}
  548. for(var i=0; i< this.extensions.length; i++){
  549. if((this.extensions[i].name_space == name_space || this.extensions[i].shortNs === name_space) && this.extensions[i].name === name){
  550. this.extensions.splice(i,1);
  551. i--;
  552. }
  553. }
  554. },
  555. destroy: function() {
  556. this.links = null;
  557. this.authors = null;
  558. this.categories = null;
  559. this.contributors = null;
  560. this.icon = this.id = this.logo = this.xmlBase = this.rights = null;
  561. this.subtitle = this.title = null;
  562. this.updated = this.published = null;
  563. // Google news
  564. this.issued = this.modified = null;
  565. this.content = null;
  566. this.extensions = null;
  567. this.entries = null;
  568. }
  569. });
  570. model.Category = dojo.declare(/*===== "dojox.atom.io.model.Category", =====*/ model.Node,{
  571. // summary:
  572. // Class container for 'Category' types.
  573. // description:
  574. // Class container for 'Category' types.
  575. constructor: function(/*String*/scheme, /*String*/term, /*String*/label){
  576. this.scheme = scheme; this.term = term; this.label = label;
  577. this._objName = "Category";//for debugging
  578. this.nodeType = "Category";
  579. },
  580. _postBuild: function(){},
  581. _getAttributeNames: function(){
  582. return ["label","scheme","term"];
  583. },
  584. toString: function(){
  585. // summary:
  586. // Function to construct string form of the category tag, which is an XML structure.
  587. // description:
  588. // Function to construct string form of the category tag, which is an XML structure.
  589. var s = [];
  590. s.push('<category ');
  591. if(this.label){s.push(' label="'+this.label+'" ');}
  592. if(this.scheme){s.push(' scheme="'+this.scheme+'" ');}
  593. if(this.term){s.push(' term="'+this.term+'" ');}
  594. s.push('/>\n');
  595. return s.join('');
  596. },
  597. buildFromDom: function(/*DOM node*/node){
  598. // summary:
  599. // Function to do construction of the Category data from the DOM node containing it.
  600. // description:
  601. // Function to do construction of the Category data from the DOM node containing it.
  602. //
  603. // node:
  604. // The DOM node to process for content.
  605. this._saveAttributes(node);//just get the attributes from the node
  606. this.label = this.attributes.label;
  607. this.scheme = this.attributes.scheme;
  608. this.term = this.attributes.term;
  609. if(this._postBuild){this._postBuild();}
  610. }
  611. });
  612. model.Content = dojo.declare(/*===== "dojox.atom.io.model.Content", =====*/ model.Node,{
  613. // summary:
  614. // Class container for 'Content' types. Such as summary, content, username, and so on types of data.
  615. // description:
  616. // Class container for 'Content' types. Such as summary, content, username, and so on types of data.
  617. constructor: function(tagName, value, src, type,xmlLang){
  618. this.tagName = tagName; this.value = value; this.src = src; this.type=type; this.xmlLang = xmlLang;
  619. this.HTML = "html"; this.TEXT = "text"; this.XHTML = "xhtml"; this.XML="xml";
  620. this._useTextContent = "true";
  621. this.nodeType = "Content";
  622. },
  623. _getAttributeNames: function(){return ["type","src"];},
  624. _postBuild: function(){},
  625. buildFromDom: function(/*DOM node*/node){
  626. // summary:
  627. // Function to do construction of the Content data from the DOM node containing it.
  628. // description:
  629. // Function to do construction of the Content data from the DOM node containing it.
  630. //
  631. // node:
  632. // The DOM node to process for content.
  633. //Handle checking for XML content as the content type
  634. var type = node.getAttribute("type");
  635. if(type){
  636. type = type.toLowerCase();
  637. if(type == "xml" || "text/xml"){
  638. type = this.XML;
  639. }
  640. }else{
  641. type="text";
  642. }
  643. if(type === this.XML){
  644. if(node.firstChild){
  645. var i;
  646. this.value = "";
  647. for(i = 0; i < node.childNodes.length; i++){
  648. var c = node.childNodes[i];
  649. if(c){
  650. this.value += parser.innerXML(c);
  651. }
  652. }
  653. }
  654. } else if(node.innerHTML){
  655. this.value = node.innerHTML;
  656. }else{
  657. this.value = parser.textContent(node);
  658. }
  659. this._saveAttributes(node);
  660. if(this.attributes){
  661. this.type = this.attributes.type;
  662. this.scheme = this.attributes.scheme;
  663. this.term = this.attributes.term;
  664. }
  665. if(!this.type){this.type = "text";}
  666. //We need to unescape the HTML content here so that it can be displayed correctly when the value is fetched.
  667. var lowerType = this.type.toLowerCase();
  668. if(lowerType === "html" || lowerType === "text/html" || lowerType === "xhtml" || lowerType === "text/xhtml"){
  669. this.value = this.value?model.util.unEscapeHtml(this.value):"";
  670. }
  671. if(this._postBuild){this._postBuild();}
  672. },
  673. toString: function(){
  674. // summary:
  675. // Function to construct string form of the content tag, which is an XML structure.
  676. // description:
  677. // Function to construct string form of the content tag, which is an XML structure.
  678. var s = [];
  679. s.push('<'+this.tagName+' ');
  680. if(!this.type){this.type = "text";}
  681. if(this.type){s.push(' type="'+this.type+'" ');}
  682. if(this.xmlLang){s.push(' xml:lang="'+this.xmlLang+'" ');}
  683. if(this.xmlBase){s.push(' xml:base="'+this.xmlBase+'" ');}
  684. //all HTML must be escaped
  685. if(this.type.toLowerCase() == this.HTML){
  686. s.push('>'+model.util.escapeHtml(this.value)+'</'+this.tagName+'>\n');
  687. }else{
  688. s.push('>'+this.value+'</'+this.tagName+'>\n');
  689. }
  690. var ret = s.join('');
  691. return ret;
  692. }
  693. });
  694. model.Link = dojo.declare(/*===== "dojox.atom.io.model.Link", =====*/ model.Node,{
  695. // summary:
  696. // Class container for 'link' types.
  697. // description:
  698. // Class container for 'link' types.
  699. constructor: function(href,rel,hrefLang,title,type){
  700. this.href = href; this.hrefLang = hrefLang; this.rel = rel; this.title = title;this.type = type;
  701. this.nodeType = "Link";
  702. },
  703. _getAttributeNames: function(){return ["href","jrefLang","rel","title","type"];},
  704. _postBuild: function(){},
  705. buildFromDom: function(node){
  706. // summary:
  707. // Function to do construction of the link data from the DOM node containing it.
  708. // description:
  709. // Function to do construction of the link data from the DOM node containing it.
  710. //
  711. // node:
  712. // The DOM node to process for link data.
  713. this._saveAttributes(node);//just get the attributes from the node
  714. this.href = this.attributes.href;
  715. this.hrefLang = this.attributes.hreflang;
  716. this.rel = this.attributes.rel;
  717. this.title = this.attributes.title;
  718. this.type = this.attributes.type;
  719. if(this._postBuild){this._postBuild();}
  720. },
  721. toString: function(){
  722. // summary:
  723. // Function to construct string form of the link tag, which is an XML structure.
  724. // description:
  725. // Function to construct string form of the link tag, which is an XML structure.
  726. var s = [];
  727. s.push('<link ');
  728. if(this.href){s.push(' href="'+this.href+'" ');}
  729. if(this.hrefLang){s.push(' hrefLang="'+this.hrefLang+'" ');}
  730. if(this.rel){s.push(' rel="'+this.rel+'" ');}
  731. if(this.title){s.push(' title="'+this.title+'" ');}
  732. if(this.type){s.push(' type = "'+this.type+'" ');}
  733. s.push('/>\n');
  734. return s.join('');
  735. }
  736. });
  737. model.Person = dojo.declare(/*===== "dojox.atom.io.model.Person", =====*/ model.Node,{
  738. // summary:
  739. // Class container for 'person' types, such as Author, controbutors, and so on.
  740. // description:
  741. // Class container for 'person' types, such as Author, controbutors, and so on.
  742. constructor: function(personType, name, email, uri){
  743. this.author = "author";
  744. this.contributor = "contributor";
  745. if(!personType){
  746. personType = this.author;
  747. }
  748. this.personType = personType;
  749. this.name = name || '';
  750. this.email = email || '';
  751. this.uri = uri || '';
  752. this._objName = "Person";//for debugging
  753. this.nodeType = "Person";
  754. },
  755. _getAttributeNames: function(){return null;},
  756. _postBuild: function(){},
  757. accept: function(tag){return Boolean(this._accepts[tag]);},
  758. buildFromDom: function(node){
  759. // summary:
  760. // Function to do construction of the person data from the DOM node containing it.
  761. // description:
  762. // Function to do construction of the person data from the DOM node containing it.
  763. //
  764. // node:
  765. // The DOM node to process for person data.
  766. var c = node.childNodes;
  767. for(var i = 0; i< c.length; i++){
  768. var name = model.util.getNodename(c[i]);
  769. if(!name){continue;}
  770. if(c[i].namespaceURI != model._Constants.ATOM_NS && name != "#text"){
  771. if(!this.extensions){this.extensions = [];}
  772. var extensionNode = new model.Node();
  773. extensionNode.buildFromDom(c[i]);
  774. this.extensions.push(extensionNode);
  775. }
  776. if(!this.accept(name.toLowerCase())){
  777. continue;
  778. }
  779. var fn = model._actions[name];
  780. if(fn) {
  781. fn(this,c[i]);
  782. }
  783. }
  784. this._saveAttributes(node);
  785. if(this._postBuild){this._postBuild();}
  786. },
  787. _accepts: {
  788. 'name': true,
  789. 'uri': true,
  790. 'email': true
  791. },
  792. toString: function(){
  793. // summary:
  794. // Function to construct string form of the Person tag, which is an XML structure.
  795. // description:
  796. // Function to construct string form of the Person tag, which is an XML structure.
  797. var s = [];
  798. s.push('<'+this.personType+'>\n');
  799. if(this.name){s.push('\t<name>'+this.name+'</name>\n');}
  800. if(this.email){s.push('\t<email>'+this.email+'</email>\n');}
  801. if(this.uri){s.push('\t<uri>'+this.uri+'</uri>\n');}
  802. s.push('</'+this.personType+'>\n');
  803. return s.join('');
  804. }
  805. });
  806. model.Generator = dojo.declare(/*===== "dojox.atom.io.model.Generator", =====*/ model.Node,{
  807. // summary:
  808. // Class container for 'Generator' types.
  809. // description:
  810. // Class container for 'Generator' types.
  811. constructor: function(/*String*/uri, /*String*/version, /*String*/value){
  812. this.uri = uri;
  813. this.version = version;
  814. this.value = value;
  815. },
  816. _postBuild: function(){},
  817. buildFromDom: function(node){
  818. // summary:
  819. // Function to do construction of the generator data from the DOM node containing it.
  820. // description:
  821. // Function to do construction of the generator data from the DOM node containing it.
  822. //
  823. // node:
  824. // The DOM node to process for link data.
  825. this.value = parser.textContent(node);
  826. this._saveAttributes(node);
  827. this.uri = this.attributes.uri;
  828. this.version = this.attributes.version;
  829. if(this._postBuild){this._postBuild();}
  830. },
  831. toString: function(){
  832. // summary:
  833. // Function to construct string form of the Generator tag, which is an XML structure.
  834. // description:
  835. // Function to construct string form of the Generator tag, which is an XML structure.
  836. var s = [];
  837. s.push('<generator ');
  838. if(this.uri){s.push(' uri="'+this.uri+'" ');}
  839. if(this.version){s.push(' version="'+this.version+'" ');}
  840. s.push('>'+this.value+'</generator>\n');
  841. var ret = s.join('');
  842. return ret;
  843. }
  844. });
  845. model.Entry = dojo.declare(/*===== "dojox.atom.io.model.Entry", =====*/ model.AtomItem,{
  846. // summary:
  847. // Class container for 'Entry' types.
  848. // description:
  849. // Class container for 'Entry' types.
  850. constructor: function(/*String*/id){
  851. this.id = id; this._objName = "Entry"; this.feedUrl = null;
  852. },
  853. _getAttributeNames: function(){return null;},
  854. _accepts: {
  855. 'author': true,
  856. 'content': true,
  857. 'category': true,
  858. 'contributor': true,
  859. 'created': true,
  860. 'id': true,
  861. 'link': true,
  862. 'published': true,
  863. 'rights': true,
  864. 'summary': true,
  865. 'title': true,
  866. 'updated': true,
  867. 'xmlbase': true,
  868. 'issued': true,
  869. 'modified': true
  870. },
  871. toString: function(amPrimary){
  872. // summary:
  873. // Function to construct string form of the entry tag, which is an XML structure.
  874. // description:
  875. // Function to construct string form of the entry tag, which is an XML structure.
  876. var s = [];
  877. var i;
  878. if(amPrimary){
  879. s.push("<?xml version='1.0' encoding='UTF-8'?>");
  880. s.push("<entry xmlns='"+model._Constants.ATOM_URI+"'");
  881. }else{s.push("<entry");}
  882. if(this.xmlBase){s.push(' xml:base="'+this.xmlBase+'" ');}
  883. for(i in this.name_spaces){s.push(' xmlns:'+i+'="'+this.name_spaces[i]+'"');}
  884. s.push('>\n');
  885. s.push('<id>' + (this.id ? this.id: '') + '</id>\n');
  886. if(this.issued && !this.published){this.published = this.issued;}
  887. if(this.published){s.push('<published>'+stamp.toISOString(this.published)+'</published>\n');}
  888. if(this.created){s.push('<created>'+stamp.toISOString(this.created)+'</created>\n');}
  889. //Google News
  890. if(this.issued){s.push('<issued>'+stamp.toISOString(this.issued)+'</issued>\n');}
  891. //Google News
  892. if(this.modified){s.push('<modified>'+stamp.toISOString(this.modified)+'</modified>\n');}
  893. if(this.modified && !this.updated){this.updated = this.modified;}
  894. if(this.updated){s.push('<updated>'+stamp.toISOString(this.updated)+'</updated>\n');}
  895. if(this.rights){s.push('<rights>'+this.rights+'</rights>\n');}
  896. if(this.title){s.push(this.title.toString());}
  897. if(this.summary){s.push(this.summary.toString());}
  898. var arrays = [this.authors,this.categories,this.links,this.contributors,this.extensions];
  899. for(var x in arrays){
  900. if(arrays[x]){
  901. for(var y in arrays[x]){
  902. s.push(arrays[x][y]);
  903. }
  904. }
  905. }
  906. if(this.content){s.push(this.content.toString());}
  907. s.push("</entry>\n");
  908. return s.join(''); //string
  909. },
  910. getEditHref: function(){
  911. // summary:
  912. // Function to get the href that allows editing of this feed entry.
  913. // description:
  914. // Function to get the href that allows editing of this feed entry.
  915. //
  916. // returns:
  917. // The href that specifies edit capability.
  918. if(this.links === null || this.links.length === 0){
  919. return null;
  920. }
  921. for(var x in this.links){
  922. if(this.links[x].rel && this.links[x].rel == "edit"){
  923. return this.links[x].href; //string
  924. }
  925. }
  926. return null;
  927. },
  928. setEditHref: function(url){
  929. if(this.links === null){
  930. this.links = [];
  931. }
  932. for(var x in this.links){
  933. if(this.links[x].rel && this.links[x].rel == "edit"){
  934. this.links[x].href = url;
  935. return;
  936. }
  937. }
  938. this.addLink(url, 'edit');
  939. }
  940. });
  941. model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.AtomItem,{
  942. // summary:
  943. // Class container for 'Feed' types.
  944. // description:
  945. // Class container for 'Feed' types.
  946. _accepts: {
  947. 'author': true,
  948. 'content': true,
  949. 'category': true,
  950. 'contributor': true,
  951. 'created': true,
  952. 'id': true,
  953. 'link': true,
  954. 'published': true,
  955. 'rights': true,
  956. 'summary': true,
  957. 'title': true,
  958. 'updated': true,
  959. 'xmlbase': true,
  960. 'entry': true,
  961. 'logo': true,
  962. 'issued': true,
  963. 'modified': true,
  964. 'icon': true,
  965. 'subtitle': true
  966. },
  967. addEntry: function(/*object*/entry){
  968. // summary:
  969. // Function to add an entry to this feed.
  970. // description:
  971. // Function to add an entry to this feed.
  972. // entry:
  973. // The entry object to add.
  974. if(!entry.id){
  975. throw new Error("The entry object must be assigned an ID attribute.");
  976. }
  977. if(!this.entries){this.entries = [];}
  978. entry.feedUrl = this.getSelfHref();
  979. this.entries.push(entry);
  980. },
  981. getFirstEntry: function(){
  982. // summary:
  983. // Function to get the first entry of the feed.
  984. // description:
  985. // Function to get the first entry of the feed.
  986. //
  987. // returns:
  988. // The first entry in the feed.
  989. if(!this.entries || this.entries.length === 0){return null;}
  990. return this.entries[0]; //object
  991. },
  992. getEntry: function(/*String*/entryId){
  993. // summary:
  994. // Function to get an entry by its id.
  995. // description:
  996. // Function to get an entry by its id.
  997. //
  998. // returns:
  999. // The entry desired, or null if none.
  1000. if(!this.entries){return null;}
  1001. for(var x in this.entries){
  1002. if(this.entries[x].id == entryId){
  1003. return this.entries[x];
  1004. }
  1005. }
  1006. return null;
  1007. },
  1008. removeEntry: function(/*object*/entry){
  1009. // summary:
  1010. // Function to remove an entry from the list of links.
  1011. // description:
  1012. // Function to remove an entry from the list of links.
  1013. //
  1014. // entry:
  1015. // The entry.
  1016. if(!this.entries){return;}
  1017. var count = 0;
  1018. for(var i = 0; i < this.entries.length; i++){
  1019. if(this.entries[i] === entry){
  1020. this.entries.splice(i,1);
  1021. count++;
  1022. }
  1023. }
  1024. return count;
  1025. },
  1026. setEntries: function(/*array*/arrayOfEntry){
  1027. // summary:
  1028. // Function to add a set of entries to the feed.
  1029. // description:
  1030. // Function to get an entry by its id.
  1031. //
  1032. // arrayOfEntry:
  1033. // An array of entry objects to add to the feed.
  1034. for(var x in arrayOfEntry){
  1035. this.addEntry(arrayOfEntry[x]);
  1036. }
  1037. },
  1038. toString: function(){
  1039. // summary:
  1040. // Function to construct string form of the feed tag, which is an XML structure.
  1041. // description:
  1042. // Function to construct string form of the feed tag, which is an XML structure.
  1043. var s = [];
  1044. var i;
  1045. s.push('<?xml version="1.0" encoding="utf-8"?>\n');
  1046. s.push('<feed xmlns="'+model._Constants.ATOM_URI+'"');
  1047. if(this.xmlBase){s.push(' xml:base="'+this.xmlBase+'"');}
  1048. for(i in this.name_spaces){s.push(' xmlns:'+i+'="'+this.name_spaces[i]+'"');}
  1049. s.push('>\n');
  1050. s.push('<id>' + (this.id ? this.id: '') + '</id>\n');
  1051. if(this.title){s.push(this.title);}
  1052. if(this.copyright && !this.rights){this.rights = this.copyright;}
  1053. if(this.rights){s.push('<rights>' + this.rights + '</rights>\n');}
  1054. // Google news
  1055. if(this.issued){s.push('<issued>'+stamp.toISOString(this.issued)+'</issued>\n');}
  1056. if(this.modified){s.push('<modified>'+stamp.toISOString(this.modified)+'</modified>\n');}
  1057. if(this.modified && !this.updated){this.updated=this.modified;}
  1058. if(this.updated){s.push('<updated>'+stamp.toISOString(this.updated)+'</updated>\n');}
  1059. if(this.published){s.push('<published>'+stamp.toISOString(this.published)+'</published>\n');}
  1060. if(this.icon){s.push('<icon>'+this.icon+'</icon>\n');}
  1061. if(this.language){s.push('<language>'+this.language+'</language>\n');}
  1062. if(this.logo){s.push('<logo>'+this.logo+'</logo>\n');}
  1063. if(this.subtitle){s.push(this.subtitle.toString());}
  1064. if(this.tagline){s.push(this.tagline.toString());}
  1065. //TODO: need to figure out what to do with xmlBase
  1066. var arrays = [this.alternateLinks,this.authors,this.categories,this.contributors,this.otherLinks,this.extensions,this.entries];
  1067. for(i in arrays){
  1068. if(arrays[i]){
  1069. for(var x in arrays[i]){
  1070. s.push(arrays[i][x]);
  1071. }
  1072. }
  1073. }
  1074. s.push('</feed>');
  1075. return s.join('');
  1076. },
  1077. createEntry: function(){
  1078. // summary:
  1079. // Function to Create a new entry object in the feed.
  1080. // description:
  1081. // Function to Create a new entry object in the feed.
  1082. // returns:
  1083. // An empty entry object in the feed.
  1084. var entry = new model.Entry();
  1085. entry.feedUrl = this.getSelfHref();
  1086. return entry; //object
  1087. },
  1088. getSelfHref: function(){
  1089. // summary:
  1090. // Function to get the href that refers to this feed.
  1091. // description:
  1092. // Function to get the href that refers to this feed.
  1093. // returns:
  1094. // The href that refers to this feed or null if none.
  1095. if(this.links === null || this.links.length === 0){
  1096. return null;
  1097. }
  1098. for(var x in this.links){
  1099. if(this.links[x].rel && this.links[x].rel == "self"){
  1100. return this.links[x].href; //string
  1101. }
  1102. }
  1103. return null;
  1104. }
  1105. });
  1106. model.Service = dojo.declare(/*===== "dojox.atom.io.model.Service", =====*/ model.AtomItem,{
  1107. // summary:
  1108. // Class container for 'Feed' types.
  1109. // description:
  1110. // Class container for 'Feed' types.
  1111. constructor: function(href){
  1112. this.href = href;
  1113. },
  1114. //builds a Service document. each element of this, except for the namespace, is the href of
  1115. //a service that the server supports. Some of the common services are:
  1116. //"create-entry" , "user-prefs" , "search-entries" , "edit-template" , "categories"
  1117. buildFromDom: function(/*DOM node*/node){
  1118. // summary:
  1119. // Function to do construction of the Service data from the DOM node containing it.
  1120. // description:
  1121. // Function to do construction of the Service data from the DOM node containing it.
  1122. //
  1123. // node:
  1124. // The DOM node to process for content.
  1125. var i;
  1126. this.workspaces = [];
  1127. if(node.tagName != "service"){
  1128. // FIXME: Need 0.9 DOM util...
  1129. //node = dojox.xml.parser.firstElement(node,"service");
  1130. //if(!node){return;}
  1131. return;
  1132. }
  1133. if(node.namespaceURI != model._Constants.PURL_NS && node.namespaceURI != model._Constants.APP_NS){return;}
  1134. var ns = node.namespaceURI;
  1135. this.name_space = node.namespaceURI;
  1136. //find all workspaces, and create them
  1137. var workspaces ;
  1138. if(typeof(node.getElementsByTagNameNS)!= "undefined"){
  1139. workspaces = node.getElementsByTagNameNS(ns,"workspace");
  1140. }else{
  1141. // This block is IE only, which doesn't have a 'getElementsByTagNameNS' function
  1142. workspaces = [];
  1143. var temp = node.getElementsByTagName('workspace');
  1144. for(i=0; i<temp.length; i++){
  1145. if(temp[i].namespaceURI == ns){
  1146. workspaces.push(temp[i]);
  1147. }
  1148. }
  1149. }
  1150. if(workspaces && workspaces.length > 0){
  1151. var wkLen = 0;
  1152. var workspace;
  1153. for(i = 0; i< workspaces.length; i++){
  1154. workspace = (typeof(workspaces.item)==="undefined"?workspaces[i]:workspaces.item(i));
  1155. var wkspace = new model.Workspace();
  1156. wkspace.buildFromDom(workspace);
  1157. this.workspaces[wkLen++] = wkspace;
  1158. }
  1159. }
  1160. },
  1161. getCollection: function(/*String*/url){
  1162. // summary:
  1163. // Function to collections that match a specific url.
  1164. // description:
  1165. // Function to collections that match a specific url.
  1166. //
  1167. // url:
  1168. // e URL to match collections against.
  1169. for(var i=0;i<this.workspaces.length;i++){
  1170. var coll=this.workspaces[i].collections;
  1171. for(var j=0;j<coll.length;j++){
  1172. if(coll[j].href == url){
  1173. return coll;
  1174. }
  1175. }
  1176. }
  1177. return null;
  1178. }
  1179. });
  1180. model.Workspace = dojo.declare(/*===== "dojox.atom.io.model.Workspace", =====*/ model.AtomItem,{
  1181. // summary:
  1182. // Class container for 'Workspace' types.
  1183. // description:
  1184. // Class container for 'Workspace' types.
  1185. constructor: function(title){
  1186. this.title = title;
  1187. this.collections = [];
  1188. },
  1189. buildFromDom: function(/*DOM node*/node){
  1190. // summary:
  1191. // Function to do construction of the Workspace data from the DOM node containing it.
  1192. // description:
  1193. // Function to do construction of the Workspace data from the DOM node containing it.
  1194. //
  1195. // node:
  1196. // The DOM node to process for content.
  1197. var name = model.util.getNodename(node);
  1198. if(name != "workspace"){return;}
  1199. var c = node.childNodes;
  1200. var len = 0;
  1201. for(var i = 0; i< c.length; i++){
  1202. var child = c[i];
  1203. if(child.nodeType === 1){
  1204. name = model.util.getNodename(child);
  1205. if(child.namespaceURI == model._Constants.PURL_NS || child.namespaceURI == model._Constants.APP_NS){
  1206. if(name === "collection"){
  1207. var coll = new model.Collection();
  1208. coll.buildFromDom(child);
  1209. this.collections[len++] = coll;
  1210. }
  1211. }else if(child.namespaceURI === model._Constants.ATOM_NS){
  1212. if(name === "title"){
  1213. this.title = parser.textContent(child);
  1214. }
  1215. }
  1216. //FIXME: Add an extension point so others can impl different namespaces. For now just
  1217. //ignore unknown namespace tags.
  1218. }
  1219. }
  1220. }
  1221. });
  1222. model.Collection = dojo.declare(/*===== "dojox.atom.io.model.Collection", =====*/ model.AtomItem,{
  1223. // summary:
  1224. // Class container for 'Collection' types.
  1225. // description:
  1226. // Class container for 'Collection' types.
  1227. constructor: function(href, title){
  1228. this.href = href;
  1229. this.title = title;
  1230. this.attributes = [];
  1231. this.features = [];
  1232. this.children = [];
  1233. this.memberType = null;
  1234. this.id = null;
  1235. },
  1236. buildFromDom: function(/*DOM node*/node){
  1237. // summary:
  1238. // Function to do construction of the Collection data from the DOM node containing it.
  1239. // description:
  1240. // Function to do construction of the Collection data from the DOM node containing it.
  1241. //
  1242. // node:
  1243. // The DOM node to process for content.
  1244. this.href = node.getAttribute("href");
  1245. var c = node.childNodes;
  1246. for(var i = 0; i< c.length; i++){
  1247. var child = c[i];
  1248. if(child.nodeType === 1){
  1249. var name = model.util.getNodename(child);
  1250. if(child.namespaceURI == model._Constants.PURL_NS || child.namespaceURI == model._Constants.APP_NS){
  1251. if(name === "member-type"){
  1252. this.memberType = parser.textContent(child);
  1253. }else if(name == "feature"){//this IF stmt might need some more work
  1254. if(child.getAttribute("id")){this.features.push(child.getAttribute("id"));}
  1255. }else{
  1256. var unknownTypeChild = new model.Node();
  1257. unknownTypeChild.buildFromDom(child);
  1258. this.children.push(unknownTypeChild);
  1259. }
  1260. }else if(child.namespaceURI === model._Constants.ATOM_NS){
  1261. if(name === "id"){
  1262. this.id = parser.textContent(child);
  1263. }else if(name === "title"){
  1264. this.title = parser.textContent(child);
  1265. }
  1266. }
  1267. }
  1268. }
  1269. }
  1270. });
  1271. return model;
  1272. });