-
-
Notifications
You must be signed in to change notification settings - Fork 108
/
XMLStringifier.coffee
99 lines (91 loc) · 2.75 KB
/
XMLStringifier.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Converts values to strings
module.exports = class XMLStringifier
# Initializes a new instance of `XMLStringifier`
#
# `options.allowSurrogateChars` whether surrogates will be allowed: true or false
# `options.stringify` a set of functions to use for converting values to strings
constructor: (options) ->
@allowSurrogateChars = options?.allowSurrogateChars
for own key, value of options?.stringify or {}
@[key] = value
# Defaults
eleName: (val) ->
val = '' + val or ''
@assertLegalChar val
eleText: (val) ->
val = '' + val or ''
@assertLegalChar @escape val
cdata: (val) ->
val = '' + val or ''
if val.match /]]>/
throw new Error "Invalid CDATA text: " + val
@assertLegalChar val
comment: (val) ->
val = '' + val or ''
if val.match /--/
throw new Error "Comment text cannot contain double-hypen: " + val
@assertLegalChar @escape val
raw: (val) ->
'' + val or ''
attName: (val) ->
'' + val or ''
attValue: (val) ->
val = '' + val or ''
@escape val
insTarget: (val) ->
'' + val or ''
insValue: (val) ->
val = '' + val or ''
if val.match /\?>/
throw new Error "Invalid processing instruction value: " + val
val
xmlVersion: (val) ->
val = '' + val or ''
if not val.match /1\.[0-9]+/
throw new Error "Invalid version number: " + val
val
xmlEncoding: (val) ->
val = '' + val or ''
if not val.match /[A-Za-z](?:[A-Za-z0-9._-]|-)*/
throw new Error "Invalid encoding: " + options.val
val
xmlStandalone: (val) ->
if val then "yes" else "no"
xmlPubID: (val) ->
'' + val or ''
xmlSysID: (val) ->
'' + val or ''
dtdElementValue: (val) ->
'' + val or ''
dtdAttType: (val) ->
'' + val or ''
dtdAttDefault: (val) ->
if val? then '' + val or '' else val
# strings to match while converting from JS objects
convertAttKey: '@'
convertPIKey: '?'
convertTextKey: '#text'
convertCDataKey: '#cdata'
convertCommentKey: '#comment'
convertRawKey: '#raw'
convertListKey: '#list'
# Checks whether the given string contains legal characters
# Fails with an exception on error
#
# `str` the string to check
assertLegalChar: (str) =>
if @allowSurrogateChars
chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/
else
chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/
chr = str.match chars
if chr
throw new Error "Invalid character (#{chr}) in string: #{str} at index #{chr.index}"
str
# Escapes special characters <, >, ', ", &
#
# `str` the string to escape
escape: (str) ->
str.replace(/&/g, '&')
.replace(/</g,'<').replace(/>/g,'>')
.replace(/'/g, ''').replace(/"/g, '"')