/[webpac2]/trunk/web/iwf/iwfxml.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/web/iwf/iwfxml.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 55 - (hide annotations)
Tue Nov 15 14:29:45 2005 UTC (18 years, 6 months ago) by dpavlin
File MIME type: text/cpp
File size: 22261 byte(s)
 r8877@llin:  dpavlin | 2005-11-14 18:40:33 +0100
 update to upstream version 0.2

1 dpavlin 55 // --------------------------------------------------------------------------
2     /// IWF - Interactive Website Framework. Javascript library for creating
3     /// responsive thin client interfaces.
4     ///
5     /// Copyright (C) 2005 Brock Weaver brockweaver@users.sourceforge.net
6     ///
7     /// This library is free software; you can redistribute it and/or modify
8     /// it under the terms of the GNU Lesser General Public License as published
9     /// by the Free Software Foundation; either version 2.1 of the License, or
10     /// (at your option) any later version.
11     ///
12     /// This library is distributed in the hope that it will be useful, but
13     /// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14     /// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15     /// License for more details.
16     ///
17     /// You should have received a copy of the GNU Lesser General Public License
18     /// along with this library; if not, write to the Free Software Foundation,
19     /// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     ///
21     /// Brock Weaver
22     /// brockweaver@users.sourceforge.net
23     /// 1605 NW Maple Pl
24     /// Ankeny, IA 50021
25     ///
26     //! http://iwf.sourceforge.net/
27     // --------------------------------------------------------------------------
28     //! NOTE: To minimize file size, strip all fluffy comments (except the LGPL, of course!)
29     //! using the following regex (global flag and multiline on):
30     //! ^\t*//([^/!].*|$)
31 dpavlin 46 //
32 dpavlin 55 // This reduces file size by about 30%, give or take.
33 dpavlin 46 //
34 dpavlin 55 //! To rip out only logging statements (commented or uncommented):
35     //! ^/{0,2}iwfLog.*
36     // --------------------------------------------------------------------------
37 dpavlin 46
38     // --------------------------------------------------------------------------
39 dpavlin 55 //! iwfxml.js
40 dpavlin 46 //
41     // Javascript-based xml parser
42     //
43 dpavlin 55 //! Dependencies:
44     //! iwfcore.js
45 dpavlin 46 //
46 dpavlin 55 //! Brock Weaver - brockweaver@users.sourceforge.net
47     //! v 0.2 - 2005-11-14
48     //! core bug patch
49 dpavlin 46 // --------------------------------------------------------------------------
50 dpavlin 55 //! Brock Weaver - brockweaver@users.sourceforge.net
51     //! v 0.1 - 2005-06-05
52     //! Initial release.
53     // --------------------------------------------------------------------------
54 dpavlin 46 // This class is meant to ease the burden of parsing xml.
55     // Xml is parsed into sets of arrays, in a hierarchical format.
56     // Each node is an array (of length 1, if applicable)
57     // The root node is an exception, as it is simply a node and not an array,
58     // as there is always only a single root node.
59     // Each attribute is a property of the current element in the node array.
60     // Useful for loading xml from server into a nice, easy-to-use format
61     // --------------------------------------------------------------------------
62    
63     if (!window.iwfGetById){
64     iwfLog("IWF Dependency Error: iwfxml.js is dependent upon iwfcore.js, so you *must* reference that file first.\n\nExample:\n\n<script type='text/javascript' src='iwfcore.js'></script>\n<script type='text/javascript' src='iwfxml.js'></script>", true);
65     }
66    
67    
68     // -----------------------------------
69     // Begin: Xml Document Object
70     // -----------------------------------
71    
72     function iwfXmlDoc(xml){
73     if (!xml || xml.length == 0){
74     return;
75     }
76     this.loadXml(xml);
77     }
78    
79     iwfXmlDoc.prototype.loadXml = function(xml){
80    
81     // note this root node is not an array, as there will always
82     // be exactly 1 root.
83     var node = new iwfXmlNode(xml);
84     this.childNodes = new Array();
85     this.childNodes.push(node);
86     this[node.nodeName] = node;
87    
88     this._html = false;
89    
90     }
91    
92     iwfXmlDoc.prototype.toString = function(pretty){
93     this._html = false;
94     return this.outerXml(pretty);
95     }
96    
97     iwfXmlDoc.prototype.outerXml = function(pretty){
98     if (!this.childNodes || this.childNodes.length < 1){
99     return null;
100     } else {
101     var writer = new iwfWriter(true, pretty, this._html);
102     return this.childNodes[0].outerXml(writer);
103     }
104     }
105    
106     // -----------------------------------
107     // End: Xml Document Object
108     // -----------------------------------
109    
110    
111     // -----------------------------------
112     // Begin: Xml Node Object
113     // -----------------------------------
114    
115    
116     // --------------------------------------------------------------------------
117 dpavlin 55 //! iwfXmlNode
118 dpavlin 46 //
119 dpavlin 55 //! Brock Weaver - brockweaver@users.sourceforge.net
120     //! v 0.1 - 2005-06-05
121     //! Initial release.
122 dpavlin 46 // --------------------------------------------------------------------------
123     // This class is used to represent a single xml node.
124     // All xml is kept except processing instructions.
125     // There are issues with "<" and ">" chars embedded within
126     // the xml as text. This is technically not valid xml, so
127     // it is technically not a problem I guess.
128    
129     function iwfXmlNode(xml, parent){
130    
131     this.childNodes = new Array();
132     this._text = '';
133     this.attributes = new Array();
134     this.attributeNames = new Array();
135     this.attributeQuotes = new Array();
136     this.nodeName = 'UNKNOWN';
137     this._parent = parent;
138     this._isEmpty = false;
139    
140    
141     if (!xml || xml.length == 0){
142     return;
143     } else {
144     this._parseXml(xml);
145     }
146    
147     this._htmlMode = false;
148    
149    
150     }
151    
152     iwfXmlNode.prototype.toString = function(innerOnly){
153     if (innerOnly){
154     return this.innerXml();
155     } else {
156     return this.outerXml();
157     }
158     }
159    
160     iwfXmlNode.prototype.outerXml = function(writer){
161     return this._serialize(writer, false);
162     }
163    
164     iwfXmlNode.prototype.innerXml = function(writer){
165     return this._serialize(writer, true)
166     }
167    
168     iwfXmlNode.prototype.outerHtml = function() {
169     this._htmlMode = true;
170     var ret = this.outerXml();
171     this._htmlMode = false;
172     return ret;
173     }
174    
175     iwfXmlNode.prototype.innerHtml = function() {
176     this._htmlMode = true;
177     var ret = this.innerXml();
178     this._htmlMode = false;
179     return ret;
180     }
181    
182     iwfXmlNode.prototype._serialize = function(writer, innerOnly){
183     var pretty = false;
184     if (typeof(writer) == 'boolean'){
185     pretty = writer;
186     writer = false;
187     }
188     if (!writer){
189     writer = new iwfWriter(true, pretty, this._htmlMode);
190     }
191    
192     if (!innerOnly){
193     writer.writeNodeOpen(this.nodeName);
194     for(var i=0;i<this.attributes.length;i++){
195     writer.writeAttribute(this.attributeNames[i], this.attributes[i], this.attributeQuotes[i]);
196     }
197     }
198    
199     writer._writeRawText(this._text);
200     for(var i=0;i<this.childNodes.length;i++){
201     this.childNodes[i].outerXml(writer);
202     }
203    
204     if (!innerOnly){
205     writer.writeNodeClose();
206     }
207    
208     return writer.toString();
209     }
210    
211     iwfXmlNode.prototype.removeAttribute = function(name){
212     for(var i=0;i<this.attributeNames.length;i++){
213     if (this.attributeNames[i] == name){
214    
215     // found the attribute. splice it out of all the arrays.
216     this.attributeQuotes.splice(j, 1);
217     this.attributeNames.splice(j, 1);
218     this.attributes.splice(j, 1);
219     // remove from our object and jump out of the loop
220     delete this[name];
221     break;
222    
223    
224     // // found the attribute. move all ones following it down one
225     // for(var j=i;j<this.attributeNames.length-1;j++){
226     // this.attributeQuotes[j] = this.attributeQuotes[j+1];
227     // this.attributeNames[j] = this.attributeNames[j+1];
228     // this.attributes[j] = this.attributes[j+1];
229     // }
230     // // pop off the last one, as it's now a duplicate
231     // this.attributeQuotes.pop();
232     // this.attributeNames.pop();
233     // this.attributes.pop();
234     // delete this[name];
235     // break;
236     }
237     }
238     }
239    
240     iwfXmlNode.prototype.removeChildNode = function(node){
241     for(var i=0;i<this.childNodes.length;i++){
242     if (node == this.childNodes[i]){
243     // remove from childNodes array
244     this.childNodes.splice(k, 1);
245     var arr = this[node.nodeName];
246     if (arr){
247     if (arr.length > 1){
248     var j = 0;
249     for(j=0;i<arr.length;i++){
250     if (arr[j] == node){
251     arr.splice(j, 1);
252     break;
253     }
254     }
255     } else {
256     delete arr;
257     }
258     }
259     break;
260     }
261     }
262     }
263    
264     iwfXmlNode.prototype.addAttribute = function(name, val, quotesToUse){
265     if (!quotesToUse){
266     // assume apostrophes
267     quotesToUse = "'";
268     }
269     if (!this[name]){
270     this.attributeQuotes.push(quotesToUse);
271     this.attributeNames.push(name);
272     this.attributes.push(val);
273     }
274     this[name] = val;
275     }
276    
277     iwfXmlNode.prototype.addChildNode = function(node, nodeName){
278     if (nodeName && nodeName.length > 0 && nodeName.indexOf("#") == 0){
279     var txt = node;
280     node = new iwfXmlNode('', this);
281     node.nodeName = nodeName;
282     node._text = txt;
283    
284    
285     // push it onto the childNodes array
286     this.childNodes.push(node);
287    
288     } else {
289    
290     // make a node object out of it if they gave us a string...
291     if (typeof(node) == 'string'){
292     node = new iwfXmlNode(node, this);
293     }
294    
295     if (node.nodeName.indexOf("#") == 0){
296     // is a special node -- duplicate names may exist...
297     node._text = txt;
298    
299     // push it onto the childNodes array
300     this.childNodes.push(node);
301    
302     } else {
303    
304     if (!this.childNodes[node.nodeName]){
305     // no other child node with this name exists yet.
306    
307     // make a new array off of our object
308     this[node.nodeName] = new Array();
309     }
310    
311     // push it onto our object's array
312     this[node.nodeName].push(node);
313    
314     // push it onto the childNodes array
315     this.childNodes.push(node);
316     }
317     }
318     }
319    
320     iwfXmlNode.prototype.getText = function(){
321     var txt = '';
322     if (this.nodeName.indexOf('#') == 0){
323     txt = this._text;
324     }
325     for(var i=0;i<this.childNodes.length;i++){
326     txt += this.childNodes[i].getText();
327     }
328     return txt;
329     }
330    
331     iwfXmlNode.prototype._parseXml = function(xml){
332    
333     var remainingXml = xml;
334    
335     while(remainingXml.length > 0){
336     var type = this._determineNodeType(remainingXml);
337     switch(type){
338     case 'open':
339     remainingXml = this._parseName(remainingXml);
340     remainingXml = this._parseAtts(remainingXml);
341     if (this._parent){
342     this._parent.addChildNode(this, null);
343     }
344    
345     if (!this._isEmpty){
346     remainingXml = this._parseChildren(remainingXml);
347     // we still need to parse out the close node, so don't jump out yet!
348     } else {
349     return remainingXml;
350     }
351     break;
352    
353     case 'text':
354     return this._parseText(remainingXml);
355    
356     case 'close':
357     return this._parseClosing(remainingXml);
358    
359     case 'end':
360     return '';
361    
362     case 'pi':
363     // return this._parsePI(remainingXml);
364     remainingXml = this._parsePI(remainingXml);
365     break;
366    
367     case 'comment':
368     return this._parseComment(remainingXml);
369    
370     case 'cdata':
371     return this._parseCDATA(remainingXml);
372    
373     case 'whitespace':
374     remainingXml = this._parseWhitespace(remainingXml);
375     if (this._parent){
376     return remainingXml;
377     }
378     break;
379    
380     default:
381     iwfLog('IWF Xml Parsing Error: undefined type of ' + type + ' returned for xml starting with "' + remainingXml + '"', true);
382     break;
383     }
384    
385     }
386    
387     }
388    
389     iwfXmlNode.prototype._determineNodeType = function(xml){
390    
391    
392     if (!xml || xml.length == 0){
393     return 'end';
394     }
395    
396     var trimmed = this.ltrim(xml);
397    
398     var firstTrimmedLt = trimmed.indexOf("<");
399    
400     switch(firstTrimmedLt){
401     case -1:
402     // this is either insignificant whitespace or text
403     if (trimmed.length == 0){
404     return 'whitespace';
405     } else {
406     return 'text';
407     }
408     case 0:
409     // this is either an open node or insignificant whitespace.
410     var firstLt = xml.indexOf("<");
411     if (firstLt > 0){
412     return 'whitespace'
413     } else {
414     switch(trimmed.charAt(1)){
415     case '?':
416     return 'pi';
417     case '!':
418     if (trimmed.substr(0,4) == '<!--'){
419     return 'comment';
420     } else if (trimmed.substr(0,9) == '<![CDATA[') {
421     return 'cdata';
422     } else {
423     return 'unknown: ' + trimmed.substr(0,10);
424     }
425     case '/':
426     return 'close';
427     default:
428     return 'open';
429     }
430     }
431    
432     default:
433     // this is a text node
434     return 'text';
435     }
436     }
437    
438     iwfXmlNode.prototype._parseName = function(xml){
439     // we know xml starts with <.
440    
441     var firstSpace = xml.indexOf(" ");
442     var firstApos = xml.indexOf("'");
443     var firstQuote = xml.indexOf('"');
444     var firstGt = xml.indexOf(">");
445    
446     if (firstGt == -1){
447     iwfLog("IWF Xml Parsing Error: Bad xml; no > found for an open node.", true);
448     return '';
449     }
450    
451     // see if it's an empty node...
452     if (xml.charAt(firstGt-1) == '/'){
453     this._isEmpty = true;
454     }
455    
456     // see if there is a possibility that atts exist
457     if (firstSpace > firstGt || firstSpace == -1){
458     if (this._isEmpty){
459     // <h1/>
460     this.nodeName = xml.substr(1,firstGt-2);
461     } else {
462     // <h1>
463     this.nodeName = xml.substr(1,firstGt-1);
464     }
465     // return starting at > so parseAtts knows there are no atts.
466     return xml.substr(firstGt);
467     } else {
468     // <h1 >
469     // <h1 att='val'>
470     // <h1 att='val'/>
471     this.nodeName = xml.substr(1,firstSpace-1);
472    
473    
474     // eat everything up to the space, return the rest
475     return xml.substr(firstSpace);
476     }
477    
478     }
479    
480     iwfXmlNode.prototype._parseAtts = function(xml){
481    
482    
483     xml = this.ltrim(xml);
484     var firstGt = xml.indexOf(">");
485     if (firstGt == -1){
486     iwfLog("IWF Xml Parsing Error: Bad xml; no > found when parsing atts for " + this.nodeName, true);
487     return '';
488     } else if (firstGt == 0){
489     // no atts.
490     return xml.substr(firstGt+1);
491     } else {
492     // at least one att exists.
493     var attxml = xml.substr(0, firstGt);
494     var re = /\s*?([^=]*?)=(['"])(.*?)(\2)/;
495     var matches= re.exec(attxml)
496     while(matches){
497     attxml = this.ltrim(attxml.substr(matches[0].length));
498     var attname = this.ltrim(matches[1]);
499     var attval = matches[3];
500     var quotesToUse = matches[2];
501     this.addAttribute(attname, attval, quotesToUse);
502    
503     re = /\s*?([^=]*?)=(['"])(.*?)(\2)/;
504     matches = re.exec(attxml);
505     }
506    
507    
508     // return everything after the end of the att list and the > which closes the start of the node.
509     return xml.substr(firstGt+1);
510     }
511     }
512    
513     iwfXmlNode.prototype._parseChildren = function(xml){
514     // we are at the > which closes the open node.
515    
516     if (xml && xml.length > 0){
517     var endnode = "</" + this.nodeName + ">";
518     while (xml && xml.length > 0 && xml.indexOf(endnode) > 0){
519    
520     // do not pass the xml to the constructor, as that may cause an infinite loop.
521     var childNode = new iwfXmlNode('', this);
522     xml = childNode._parseXml(xml);
523     }
524    
525     // note we don't cut off the close node here, as the _parseXml function will do this for us.
526    
527     }
528    
529     return xml;
530     }
531    
532    
533    
534     iwfXmlNode.prototype._parseClosing = function(xml){
535     var firstGt = xml.indexOf("</");
536     if (firstGt == -1){
537     iwfLog('IWF Xml Parsing Error: Bad xml; no </' + this.nodeName + ' found', true);
538     return '';
539     } else {
540     var firstLt = xml.indexOf(">",firstGt);
541     if (firstLt == -1){
542     iwfLog('IWF Xml Parsing Error: Bad xml; no > found after </' + this.nodeName, true);
543     return '';
544     } else {
545     var result = xml.substr(firstLt+1);
546     return result;
547     }
548     }
549     }
550    
551     iwfXmlNode.prototype._parseText = function(xml){
552     return this._parsePoundNode(xml, "#text", "", "<", false);
553     }
554    
555     iwfXmlNode.prototype._parsePI = function(xml){
556     var result = this._eatXml(xml, "?>", true);
557     return result;
558     }
559    
560     iwfXmlNode.prototype._parseComment = function(xml){
561     return this._parsePoundNode(xml, "#comment", "<!--", "-->", true);
562     }
563    
564     iwfXmlNode.prototype._parseCDATA = function(xml){
565     return this._parsePoundNode(xml, "#cdata", "<![CDATA[", "]]>", true);
566     }
567    
568     iwfXmlNode.prototype._parseWhitespace = function(xml){
569     var result = '';
570     if (this._parent && this._parent.nodeName.toLowerCase() == 'pre'){
571     // hack for supporting HTML's <pre> node. ugly, I know :)
572     result = this._parsePoundNode(xml, "#text", "", "<", false);
573     } else {
574     // whitespace is insignificant otherwise
575     result = this._eatXml(xml, "<", false);
576     }
577     return result;
578     }
579    
580     iwfXmlNode.prototype._parsePoundNode = function(xml, nodeName, beginMoniker, endMoniker, eatMoniker){
581     // simply slurp everything up until the first endMoniker, starting after the beginMoniker
582     var end = xml.indexOf(endMoniker);
583     if (end == -1){
584     iwfLog("IWF Xml Parsing Error: Bad xml: " + nodeName + " does not have ending " + endMoniker, true);
585     return '';
586     } else {
587     var len = beginMoniker.length;
588     var s = xml.substr(len, end - len);
589     if (this._parent){
590     this._parent.addChildNode(s, nodeName);
591     }
592     var result = xml.substr(end + (eatMoniker ? endMoniker.length : 0));
593     return result;
594     }
595     }
596    
597     iwfXmlNode.prototype._eatXml = function(xml, moniker, eatMoniker){
598     var pos = xml.indexOf(moniker);
599    
600     if (eatMoniker){
601     pos += moniker.length;
602     }
603    
604     return xml.substr(pos);
605    
606     }
607    
608     iwfXmlNode.prototype.trim = function(s){
609     return s.replace(/^\s*|\s*$/g,"");
610     }
611    
612     iwfXmlNode.prototype.ltrim = function(s){
613     return s.replace(/^\s*/g,"");
614     }
615    
616     iwfXmlNode.prototype.rtrim = function(s){
617     return s.replace(/\s*$/g,"");
618     }
619    
620     // -----------------------------------
621     // End: Xml Node Object
622     // -----------------------------------
623    
624    
625    
626    
627    
628    
629    
630     // -----------------------------------
631     // Begin: Xml Writer Object
632     // -----------------------------------
633    
634    
635     // --------------------------------------------------------------------------
636 dpavlin 55 //! iwfWriter
637 dpavlin 46 //
638 dpavlin 55 //! Brock Weaver - brockweaver@users.sourceforge.net
639 dpavlin 46 //
640 dpavlin 55 //! v 0.1 - 2005-06-05
641     //! Initial release.
642 dpavlin 46 // --------------------------------------------------------------------------
643     // This class is meant to ease the creation of xml strings.
644     // Note it is not a fully-compliant xml generator.
645     // --------------------------------------------------------------------------
646    
647    
648     function iwfWriter(suppressProcessingInstruction, prettyPrint, htmlMode) {
649     this._buffer = new String();
650     if (!suppressProcessingInstruction){
651     this.writeRaw("<?xml version='1.0' ?>");
652     }
653     this._nodeStack = new Array();
654     this._nodeOpened = false;
655     this._prettyPrint = prettyPrint;
656     this._htmlMode = htmlMode
657     }
658    
659     iwfWriter.prototype.writePretty = function(lfBeforeTabbing){
660     if (this._prettyPrint){
661     if (lfBeforeTabbing){
662     this.writeRaw('\n');
663     }
664    
665     // assumption is most xml won't have a maximum node depth exceeding 30...
666     var tabs = '\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t';
667     while (tabs.length < this._nodeStack.length){
668     // but some xml might exceed node depth of 30, so keep tacking on another 30 tabs until we have enough...
669     // I know this is an awkward way of doing it, but I wanted to avoid looping and concatenating for "most" xml...
670     tabs += tabs;
671     }
672     this.writeRaw(tabs.substr(0,this._nodeStack.length));
673     }
674     }
675    
676     iwfWriter.prototype.writeNode = function(name, txt){
677     this.writeNodeOpen(name);
678     this.writeText(txt);
679     this.writeNodeClose();
680     }
681    
682     iwfWriter.prototype.writeNodeOpen = function(name){
683     if (this._nodeOpened){
684     this.writeRaw(">");
685     }
686     this._nodeOpened = false;
687    
688     this.writePretty(true);
689    
690     switch(name){
691     case '#pi':
692     this.writeRaw('<?');
693     break;
694     case '#text':
695     // do nothing
696     break;
697     case '#cdata':
698     this.writeRaw('<![CDATA[');
699     break;
700     case '#comment':
701     this.writeRaw('<!--');
702     break;
703     default:
704     this.writeRaw("<" + name);
705     this._nodeOpened = true;
706     break;
707     }
708     this._nodeStack.push(name);
709     }
710    
711     iwfWriter.prototype.writeAttribute = function(name, val, quotes){
712     if (!this._nodeOpened){
713     iwfLog("IWF Xml Parsing Error: Appending attribute '" + name +
714     "' when no open node exists!", true);
715     }
716     var attval = val;
717    
718    
719     if (!quotes){
720     quotes = "'";
721     }
722    
723     // browsers handle html attributes in a special way:
724     // only the character that matches the html delimiter for the attribute should be xml-escaped.
725     // the OTHER quote character (' or ", whichever) needs to be javascript-escaped,
726     //
727     // the iwfXmlNode class also needs the > char escaped to be functional -- I need to fix that!
728     // But for right now, this hack gets things working at least.
729     //
730     // Like I said, I'm getting lazy :)
731     //
732    
733     if (this._htmlMode){
734     // we're kicking out html, so xml escape only the quote character that matches the delimiter and the > sign.
735     // We also need to javascript-escape the quote char that DOES NOT match the delimiter but is xml-escaped.
736     if (quotes == "'"){
737     // we're using apostrophes to delimit html.
738     attval = attval.replace(/&quot;/gi, '\\"').replace(/'/gi, '&apos;').replace(/>/gi, '&gt;');
739     } else {
740     // we're using quotes to delimit html
741     attval = attval.replace(/&apos;/gi, "\\'").replace(/"/gi, '&quot;').replace(/>/gi, '&gt;');
742     }
743     } else {
744     attval = iwfXmlEncode(attval);
745     }
746    
747     this.writeRaw(" " + name + "=" + quotes + attval + quotes);
748     }
749    
750     iwfWriter.prototype.writeAtt = function(name, val, quotes){
751     this.writeAttribute(name, val, quotes);
752     }
753    
754     iwfWriter.prototype._writeRawText = function(txt){
755     if (!txt || txt.length == 0){
756     // no text to write. do nothing.
757     return;
758     } else {
759     if (this._nodeOpened){
760     this.writeRaw(">");
761     this._nodeOpened = false;
762     }
763    
764     this.writeRaw(txt);
765     }
766     }
767    
768     iwfWriter.prototype.writeText = function(txt){
769     if (!txt || txt.length == 0){
770     // no text to write. do nothing.
771     return;
772     } else {
773     if (this._nodeOpened){
774     this.writeRaw(">");
775     this._nodeOpened = false;
776     this.writePretty(true);
777     }
778    
779     this.writeRaw(iwfXmlEncode(txt));
780     }
781     }
782    
783     iwfWriter.prototype.writeNodeClose = function(){
784     if (this._nodeStack.length > 0){
785     var name = this._nodeStack.pop();
786    
787     if (!this._nodeOpened && name != '#text'){
788     this.writePretty(true);
789     }
790    
791     switch(name){
792     case '#pi':
793     this.writeRaw("?>");
794     break;
795     case '#text':
796     // do nothing
797     break;
798     case '#cdata':
799     this.writeRaw("]]>");
800     break;
801     case '#comment':
802     this.writeRaw("-->");
803     break;
804     default:
805     if (this._nodeOpened){
806 dpavlin 55 //! hack for <script /> and <div /> needing to be <script></script> or <div></div>
807 dpavlin 46 switch(name){
808     case 'script':
809 dpavlin 55 case 'div':
810 dpavlin 46 this.writeRaw("></" + name + ">");
811     break;
812     default:
813     this.writeRaw("/>");;
814     break;
815     }
816     } else {
817     this.writeRaw("</" + name + ">");
818     }
819     break;
820     }
821     this._nodeOpened = false;
822     }
823     }
824    
825     iwfWriter.prototype.writeRaw = function(xml){
826     this._buffer += xml;
827     }
828    
829     iwfWriter.prototype.toString = function(){
830     return this._buffer;
831     }
832    
833     iwfWriter.prototype.clear = function(){
834     this.buffer = new String();
835     }
836    
837     // -----------------------------------
838     // End: Xml Writer Object
839     // -----------------------------------
840    

Properties

Name Value
svn:mime-type text/cpp

  ViewVC Help
Powered by ViewVC 1.1.26