Mercurial > eldonilo > barbecue
comparison sxe-document.js @ 5:03ef53b969bd
Add XMPP support.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 31 Jan 2012 01:09:41 +0100 |
parents | |
children | 24aa8dccb170 |
comparison
equal
deleted
inserted
replaced
4:95c6fa5f4715 | 5:03ef53b969bd |
---|---|
1 'use strict'; | |
2 | |
3 var Document = function(initiator, name, host, domId, prolog) { | |
4 this.initiator = initiator; | |
5 this.name = name; | |
6 this.host = host; | |
7 | |
8 this.prolog = prolog || 'data:application/xhtml+xml,%3C%3Fxml%20version%3D%271.0%27%3F%3E%0A%3C%21DOCTYPE%20html%3E%0A'; | |
9 this.state = 'not-started'; | |
10 this.records = {}; | |
11 this.dom = document.getElementById(domId); | |
12 }; | |
13 | |
14 Document.prototype = { | |
15 add: function(jid, child) { | |
16 var record = new Record(jid, child); | |
17 | |
18 if (record.rid in this.records) | |
19 console.log('duplicate new'); | |
20 | |
21 this.records[record.rid] = record; | |
22 record.toDOM(this.records, this.dom); | |
23 }, | |
24 update: function(jid, child) { | |
25 var target = child.getAttributeNS(null, 'target'); | |
26 | |
27 if (!(target in this.records)) | |
28 return; // Ignore it. | |
29 | |
30 var record = this.records[target]; | |
31 console.log(record, child); | |
32 child.setAttributeNS(null, 'rid', target); | |
33 | |
34 var version = +child.getAttributeNS(null, 'version'); | |
35 if (this.state === 'getting-state') | |
36 record.version = version; | |
37 else | |
38 record.version++; | |
39 | |
40 if (record.version === version) { | |
41 var type = child.getAttributeNS(null, 'type'); | |
42 if (type === 'text' || type === 'attr' || type === 'comment') { | |
43 var chdata = child.getAttributeNS(null, 'chdata'); | |
44 var replacefrom = +child.getAttributeNS(null, 'replacefrom'); | |
45 var replacen = +child.getAttributeNS(null, 'replacen'); | |
46 if (chdata && replacefrom && replacen) { | |
47 var string = record.chdata.substr(0, replacefrom); | |
48 string += chdata; | |
49 string += record.chdata.substr(replacefrom + replacen); | |
50 child.removeAttributeNS(null, 'replacefrom'); | |
51 child.removeAttributeNS(null, 'replacen'); | |
52 child.setAttributeNS(null, 'chdata', string); | |
53 } | |
54 } | |
55 record.update(jid, child); | |
56 record.toDOM(this.records, this.dom); | |
57 } else | |
58 ; // Not sure I understand correctly. | |
59 }, | |
60 remove: function(jid, child) { | |
61 var rid = child.getAttributeNS(null, 'target'); | |
62 this.records[rid].remove(this.records); | |
63 delete this.records[rid]; | |
64 }, | |
65 processState: function(jid, elements) { | |
66 var i = 0; | |
67 var first = elements[0]; | |
68 if (first.localName === 'document-begin') { | |
69 if (this.state !== 'not-started') | |
70 return; //TODO: the session has already started. | |
71 i = 1; | |
72 this.prolog = first.getAttributeNS(null, 'prolog'); | |
73 this.state = 'getting-session'; | |
74 } | |
75 | |
76 //TODO: if the session isn’t started, should ignore changes? | |
77 | |
78 for (; i < elements.length; i++) { | |
79 var child = elements[i]; | |
80 var change = child.localName; | |
81 | |
82 switch (change) { | |
83 case 'new': | |
84 doc.add(jid, child); | |
85 break; | |
86 case 'set': | |
87 doc.update(jid, child); | |
88 break; | |
89 case 'remove': | |
90 doc.remove(jid, child); | |
91 break; | |
92 case 'document-end': | |
93 this.state = 'started'; | |
94 break; | |
95 } | |
96 } | |
97 }, | |
98 createState: function(root, parent, state) { | |
99 var children = root.childNodes; | |
100 for (var i = 0; i < children.length; i++) { | |
101 var child = children[i]; | |
102 var element = document.createElementNS(Lightstring.NS.sxe, 'new'); | |
103 var rid = Lightstring.newId('GUID'); | |
104 element.setAttributeNS(null, 'rid', rid); | |
105 | |
106 if (parent) | |
107 element.setAttributeNS(null, 'parent', parent); | |
108 | |
109 switch (child.nodeType) { | |
110 case 1: | |
111 element.setAttributeNS(null, 'type', 'element'); | |
112 element.setAttributeNS(null, 'ns', child.namespaceURI); | |
113 element.setAttributeNS(null, 'name', child.localName); | |
114 state.push(element); | |
115 | |
116 //TODO: move that elsewhere, or make it prettier. | |
117 var convertAttr = function(attr) { | |
118 var element = document.createElementNS(Lightstring.NS.sxe, 'new'); | |
119 var arid = Lightstring.newId('GUID'); | |
120 element.setAttributeNS(null, 'rid', arid); | |
121 element.setAttributeNS(null, 'parent', rid); | |
122 if (attr.namespaceURI) | |
123 element.setAttributeNS(null, 'ns', attr.namespaceURI); | |
124 element.setAttributeNS(null, 'name', attr.localName); | |
125 element.setAttributeNS(null, 'chdata', attr.textContent); | |
126 state.push(element); | |
127 }; | |
128 | |
129 for (var j = 0; j < child.attributes.length; j++) | |
130 convertAttr(child.attributes[j]); | |
131 | |
132 state = this.createState(child, rid, state); | |
133 break; | |
134 | |
135 case 3: | |
136 element.setAttributeNS(null, 'type', 'text'); | |
137 element.setAttributeNS(null, 'chdata', child.textContent); | |
138 state.push(element); | |
139 break; | |
140 | |
141 case 7: | |
142 element.setAttributeNS(null, 'type', 'processinginstruction'); | |
143 element.setAttributeNS(null, 'pitarget', child.target); | |
144 element.setAttributeNS(null, 'pidata', child.data); | |
145 state.push(element); | |
146 break; | |
147 | |
148 case 8: | |
149 element.setAttributeNS(null, 'type', 'comment'); | |
150 element.setAttributeNS(null, 'chdata', child.textContent); | |
151 state.push(element); | |
152 break; | |
153 } | |
154 } | |
155 return state; | |
156 } | |
157 }; |