00001
00002 (function() {
00003 var XMLStringifier, camelCase, kebabCase, ref, snakeCase, titleCase,
00004 bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
00005 hasProp = {}.hasOwnProperty;
00006
00007 ref = require('./Utility'), camelCase = ref.camelCase, titleCase = ref.titleCase, kebabCase = ref.kebabCase, snakeCase = ref.snakeCase;
00008
00009 module.exports = XMLStringifier = (function() {
00010 function XMLStringifier(options) {
00011 this.assertLegalChar = bind(this.assertLegalChar, this);
00012 var key, ref1, value;
00013 options || (options = {});
00014 this.allowSurrogateChars = options.allowSurrogateChars;
00015 this.noDoubleEncoding = options.noDoubleEncoding;
00016 this.textCase = options.textCase;
00017 ref1 = options.stringify || {};
00018 for (key in ref1) {
00019 if (!hasProp.call(ref1, key)) continue;
00020 value = ref1[key];
00021 this[key] = value;
00022 }
00023 }
00024
00025 XMLStringifier.prototype.eleName = function(val) {
00026 val = '' + val || '';
00027 val = this.applyCase(val);
00028 return this.assertLegalChar(val);
00029 };
00030
00031 XMLStringifier.prototype.eleText = function(val) {
00032 val = '' + val || '';
00033 return this.assertLegalChar(this.elEscape(val));
00034 };
00035
00036 XMLStringifier.prototype.cdata = function(val) {
00037 val = '' + val || '';
00038 val = val.replace(']]>', ']]]]><![CDATA[>');
00039 return this.assertLegalChar(val);
00040 };
00041
00042 XMLStringifier.prototype.comment = function(val) {
00043 val = '' + val || '';
00044 if (val.match(/--/)) {
00045 throw new Error("Comment text cannot contain double-hypen: " + val);
00046 }
00047 return this.assertLegalChar(val);
00048 };
00049
00050 XMLStringifier.prototype.raw = function(val) {
00051 return '' + val || '';
00052 };
00053
00054 XMLStringifier.prototype.attName = function(val) {
00055 val = '' + val || '';
00056 return val = this.applyCase(val);
00057 };
00058
00059 XMLStringifier.prototype.attValue = function(val) {
00060 val = '' + val || '';
00061 return this.attEscape(val);
00062 };
00063
00064 XMLStringifier.prototype.insTarget = function(val) {
00065 return '' + val || '';
00066 };
00067
00068 XMLStringifier.prototype.insValue = function(val) {
00069 val = '' + val || '';
00070 if (val.match(/\?>/)) {
00071 throw new Error("Invalid processing instruction value: " + val);
00072 }
00073 return val;
00074 };
00075
00076 XMLStringifier.prototype.xmlVersion = function(val) {
00077 val = '' + val || '';
00078 if (!val.match(/1\.[0-9]+/)) {
00079 throw new Error("Invalid version number: " + val);
00080 }
00081 return val;
00082 };
00083
00084 XMLStringifier.prototype.xmlEncoding = function(val) {
00085 val = '' + val || '';
00086 if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-]|-)*$/)) {
00087 throw new Error("Invalid encoding: " + val);
00088 }
00089 return val;
00090 };
00091
00092 XMLStringifier.prototype.xmlStandalone = function(val) {
00093 if (val) {
00094 return "yes";
00095 } else {
00096 return "no";
00097 }
00098 };
00099
00100 XMLStringifier.prototype.dtdPubID = function(val) {
00101 return '' + val || '';
00102 };
00103
00104 XMLStringifier.prototype.dtdSysID = function(val) {
00105 return '' + val || '';
00106 };
00107
00108 XMLStringifier.prototype.dtdElementValue = function(val) {
00109 return '' + val || '';
00110 };
00111
00112 XMLStringifier.prototype.dtdAttType = function(val) {
00113 return '' + val || '';
00114 };
00115
00116 XMLStringifier.prototype.dtdAttDefault = function(val) {
00117 if (val != null) {
00118 return '' + val || '';
00119 } else {
00120 return val;
00121 }
00122 };
00123
00124 XMLStringifier.prototype.dtdEntityValue = function(val) {
00125 return '' + val || '';
00126 };
00127
00128 XMLStringifier.prototype.dtdNData = function(val) {
00129 return '' + val || '';
00130 };
00131
00132 XMLStringifier.prototype.convertAttKey = '@';
00133
00134 XMLStringifier.prototype.convertPIKey = '?';
00135
00136 XMLStringifier.prototype.convertTextKey = '#text';
00137
00138 XMLStringifier.prototype.convertCDataKey = '#cdata';
00139
00140 XMLStringifier.prototype.convertCommentKey = '#comment';
00141
00142 XMLStringifier.prototype.convertRawKey = '#raw';
00143
00144 XMLStringifier.prototype.assertLegalChar = function(str) {
00145 var chars, chr;
00146 if (this.allowSurrogateChars) {
00147 chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/;
00148 } else {
00149 chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/;
00150 }
00151 chr = str.match(chars);
00152 if (chr) {
00153 throw new Error("Invalid character (" + chr + ") in string: " + str + " at index " + chr.index);
00154 }
00155 return str;
00156 };
00157
00158 XMLStringifier.prototype.applyCase = function(str) {
00159 switch (this.textCase) {
00160 case "camel":
00161 return camelCase(str);
00162 case "title":
00163 return titleCase(str);
00164 case "kebab":
00165 case "lower":
00166 return kebabCase(str);
00167 case "snake":
00168 return snakeCase(str);
00169 case "upper":
00170 return kebabCase(str).toUpperCase();
00171 default:
00172 return str;
00173 }
00174 };
00175
00176 XMLStringifier.prototype.elEscape = function(str) {
00177 var ampregex;
00178 ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g;
00179 return str.replace(ampregex, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\r/g, '
');
00180 };
00181
00182 XMLStringifier.prototype.attEscape = function(str) {
00183 var ampregex;
00184 ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g;
00185 return str.replace(ampregex, '&').replace(/</g, '<').replace(/"/g, '"').replace(/\t/g, '	').replace(/\n/g, '
').replace(/\r/g, '
');
00186 };
00187
00188 return XMLStringifier;
00189
00190 })();
00191
00192 }).call(this);