1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * A SAX Parser
 29  * @namespace
 30  * @name cc.saxParser
 31  */
 32 cc.SAXParser = cc.Class.extend(/** @lends cc.saxParser# */{
 33     _parser: null,
 34     _isSupportDOMParser: null,
 35 
 36     ctor: function () {
 37         if (window.DOMParser) {
 38             this._isSupportDOMParser = true;
 39             this._parser = new DOMParser();
 40         } else {
 41             this._isSupportDOMParser = false;
 42         }
 43     },
 44 
 45     parse : function(xmlTxt){
 46         return this._parseXML(xmlTxt);
 47     },
 48 
 49     _parseXML: function (textxml) {
 50         // get a reference to the requested corresponding xml file
 51         var xmlDoc;
 52         if (this._isSupportDOMParser) {
 53             xmlDoc = this._parser.parseFromString(textxml, "text/xml");
 54         } else {
 55             // Internet Explorer (untested!)
 56             xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
 57             xmlDoc.async = "false";
 58             xmlDoc.loadXML(textxml);
 59         }
 60         return xmlDoc;
 61     }
 62 
 63 });
 64 
 65 /**
 66  *
 67  * A plist Parser
 68  * @namespace
 69  * @name cc.plistParser
 70  */
 71 cc.PlistParser = cc.SAXParser.extend(/** @lends cc.plistParser# */{
 72 
 73     /**
 74      * parse a xml string as plist object.
 75      * @param {String} xmlTxt plist xml contents
 76      * @return {*} plist object
 77      */
 78     parse : function (xmlTxt) {
 79         var xmlDoc = this._parseXML(xmlTxt);
 80         var plist = xmlDoc.documentElement;
 81         if (plist.tagName != 'plist')
 82             throw "Not a plist file!";
 83 
 84         // Get first real node
 85         var node = null;
 86         for (var i = 0, len = plist.childNodes.length; i < len; i++) {
 87             node = plist.childNodes[i];
 88             if (node.nodeType == 1)
 89                 break;
 90         }
 91         xmlDoc = null;
 92         return this._parseNode(node);
 93     },
 94 
 95     _parseNode: function (node) {
 96         var data = null, tagName = node.tagName;
 97         if(tagName == "dict"){
 98             data = this._parseDict(node);
 99         }else if(tagName == "array"){
100             data = this._parseArray(node);
101         }else if(tagName == "string"){
102             if (node.childNodes.length == 1)
103                 data = node.firstChild.nodeValue;
104             else {
105                 //handle Firefox's 4KB nodeValue limit
106                 data = "";
107                 for (var i = 0; i < node.childNodes.length; i++)
108                     data += node.childNodes[i].nodeValue;
109             }
110         }else if(tagName == "false"){
111             data = false;
112         }else if(tagName == "true"){
113             data = true;
114         }else if(tagName == "real"){
115             data = parseFloat(node.firstChild.nodeValue);
116         }else if(tagName == "integer"){
117             data = parseInt(node.firstChild.nodeValue, 10);
118         }
119         return data;
120     },
121 
122     _parseArray: function (node) {
123         var data = [];
124         for (var i = 0, len = node.childNodes.length; i < len; i++) {
125             var child = node.childNodes[i];
126             if (child.nodeType != 1)
127                 continue;
128             data.push(this._parseNode(child));
129         }
130         return data;
131     },
132 
133     _parseDict: function (node) {
134         var data = {};
135         var key = null;
136         for (var i = 0, len = node.childNodes.length; i < len; i++) {
137             var child = node.childNodes[i];
138             if (child.nodeType != 1)
139                 continue;
140 
141             // Grab the key, next noe should be the value
142             if (child.tagName == 'key')
143                 key = child.firstChild.nodeValue;
144             else
145                 data[key] = this._parseNode(child);                 // Parse the value node
146         }
147         return data;
148     }
149 
150 });