Mercurial > eldonilo > barbecue
annotate sxe-document.js @ 9:d3b37bbb2b88 default tip master
Support multiple participants.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 02 Feb 2012 16:37:28 +0100 |
parents | 7b2ca4d5af6d |
children |
rev | line source |
---|---|
5 | 1 'use strict'; |
2 | |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
3 /** Copyright (c) 2012 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
4 * |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
5 * Permission is hereby granted, free of charge, to any person obtaining a copy |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
6 * of this software and associated documentation files (the "Software"), to |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
7 * deal in the Software without restriction, including without limitation the |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
9 * sell copies of the Software, and to permit persons to whom the Software is |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
10 * furnished to do so, subject to the following conditions: |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
11 * |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
12 * The above copyright notice and this permission notice shall be included in |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
13 * all copies or substantial portions of the Software. |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
14 * |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
21 * IN THE SOFTWARE. |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
22 */ |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
23 |
5 | 24 var Document = function(initiator, name, host, domId, prolog) { |
25 this.initiator = initiator; | |
26 this.name = name; | |
27 this.host = host; | |
8
7b2ca4d5af6d
Add a resend-whole-state button and make it works.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
6
diff
changeset
|
28 this.participants = {}; |
5 | 29 |
30 this.prolog = prolog || 'data:application/xhtml+xml,%3C%3Fxml%20version%3D%271.0%27%3F%3E%0A%3C%21DOCTYPE%20html%3E%0A'; | |
31 this.state = 'not-started'; | |
32 this.records = {}; | |
33 this.dom = document.getElementById(domId); | |
34 }; | |
35 | |
36 Document.prototype = { | |
37 add: function(jid, child) { | |
38 var record = new Record(jid, child); | |
39 | |
40 if (record.rid in this.records) | |
41 console.log('duplicate new'); | |
42 | |
43 this.records[record.rid] = record; | |
44 record.toDOM(this.records, this.dom); | |
45 }, | |
46 update: function(jid, child) { | |
47 var target = child.getAttributeNS(null, 'target'); | |
48 | |
49 if (!(target in this.records)) | |
50 return; // Ignore it. | |
51 | |
52 var record = this.records[target]; | |
53 console.log(record, child); | |
54 child.setAttributeNS(null, 'rid', target); | |
55 | |
56 var version = +child.getAttributeNS(null, 'version'); | |
57 if (this.state === 'getting-state') | |
58 record.version = version; | |
59 else | |
60 record.version++; | |
61 | |
62 if (record.version === version) { | |
63 var type = child.getAttributeNS(null, 'type'); | |
64 if (type === 'text' || type === 'attr' || type === 'comment') { | |
65 var chdata = child.getAttributeNS(null, 'chdata'); | |
66 var replacefrom = +child.getAttributeNS(null, 'replacefrom'); | |
67 var replacen = +child.getAttributeNS(null, 'replacen'); | |
68 if (chdata && replacefrom && replacen) { | |
69 var string = record.chdata.substr(0, replacefrom); | |
70 string += chdata; | |
71 string += record.chdata.substr(replacefrom + replacen); | |
72 child.removeAttributeNS(null, 'replacefrom'); | |
73 child.removeAttributeNS(null, 'replacen'); | |
74 child.setAttributeNS(null, 'chdata', string); | |
75 } | |
76 } | |
77 record.update(jid, child); | |
78 record.toDOM(this.records, this.dom); | |
79 } else | |
80 ; // Not sure I understand correctly. | |
81 }, | |
82 remove: function(jid, child) { | |
83 var rid = child.getAttributeNS(null, 'target'); | |
84 this.records[rid].remove(this.records); | |
85 delete this.records[rid]; | |
86 }, | |
87 processState: function(jid, elements) { | |
88 var i = 0; | |
89 var first = elements[0]; | |
90 if (first.localName === 'document-begin') { | |
8
7b2ca4d5af6d
Add a resend-whole-state button and make it works.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
6
diff
changeset
|
91 /*if (this.state !== 'not-started') |
7b2ca4d5af6d
Add a resend-whole-state button and make it works.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
6
diff
changeset
|
92 return;*/ //TODO: the session has already started. |
5 | 93 i = 1; |
94 this.prolog = first.getAttributeNS(null, 'prolog'); | |
95 this.state = 'getting-session'; | |
96 } | |
97 | |
98 //TODO: if the session isn’t started, should ignore changes? | |
99 | |
100 for (; i < elements.length; i++) { | |
101 var child = elements[i]; | |
102 var change = child.localName; | |
103 | |
104 switch (change) { | |
105 case 'new': | |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
106 this.add(jid, child); |
5 | 107 break; |
108 case 'set': | |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
109 this.update(jid, child); |
5 | 110 break; |
111 case 'remove': | |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
112 this.remove(jid, child); |
5 | 113 break; |
114 case 'document-end': | |
115 this.state = 'started'; | |
116 break; | |
117 } | |
118 } | |
119 }, | |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
120 createState: function(state, root, parent) { |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
121 if (!root) |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
122 root = this.dom; |
5 | 123 var children = root.childNodes; |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
124 |
5 | 125 for (var i = 0; i < children.length; i++) { |
126 var child = children[i]; | |
8
7b2ca4d5af6d
Add a resend-whole-state button and make it works.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
6
diff
changeset
|
127 var element = document.createElementNS(Lightstring.ns['sxe'], 'new'); |
5 | 128 var rid = Lightstring.newId('GUID'); |
129 element.setAttributeNS(null, 'rid', rid); | |
130 | |
131 if (parent) | |
132 element.setAttributeNS(null, 'parent', parent); | |
133 | |
134 switch (child.nodeType) { | |
135 case 1: | |
136 element.setAttributeNS(null, 'type', 'element'); | |
137 element.setAttributeNS(null, 'ns', child.namespaceURI); | |
138 element.setAttributeNS(null, 'name', child.localName); | |
139 state.push(element); | |
140 | |
141 //TODO: move that elsewhere, or make it prettier. | |
142 var convertAttr = function(attr) { | |
8
7b2ca4d5af6d
Add a resend-whole-state button and make it works.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
6
diff
changeset
|
143 var element = document.createElementNS(Lightstring.ns['sxe'], 'new'); |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
144 element.setAttributeNS(null, 'type', 'attr'); |
5 | 145 var arid = Lightstring.newId('GUID'); |
146 element.setAttributeNS(null, 'rid', arid); | |
147 element.setAttributeNS(null, 'parent', rid); | |
148 if (attr.namespaceURI) | |
149 element.setAttributeNS(null, 'ns', attr.namespaceURI); | |
150 element.setAttributeNS(null, 'name', attr.localName); | |
151 element.setAttributeNS(null, 'chdata', attr.textContent); | |
152 state.push(element); | |
153 }; | |
154 | |
155 for (var j = 0; j < child.attributes.length; j++) | |
156 convertAttr(child.attributes[j]); | |
157 | |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
158 state = this.createState(state, child, rid); |
5 | 159 break; |
160 | |
161 case 3: | |
162 element.setAttributeNS(null, 'type', 'text'); | |
163 element.setAttributeNS(null, 'chdata', child.textContent); | |
164 state.push(element); | |
165 break; | |
166 | |
167 case 7: | |
168 element.setAttributeNS(null, 'type', 'processinginstruction'); | |
169 element.setAttributeNS(null, 'pitarget', child.target); | |
170 element.setAttributeNS(null, 'pidata', child.data); | |
171 state.push(element); | |
172 break; | |
173 | |
174 case 8: | |
175 element.setAttributeNS(null, 'type', 'comment'); | |
176 element.setAttributeNS(null, 'chdata', child.textContent); | |
177 state.push(element); | |
178 break; | |
179 } | |
180 } | |
181 return state; | |
6
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
182 }, |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
183 empty: function() { |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
184 var children = this.dom.childNodes; |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
185 for (var i = children.length - 1; i >= 0; i--) |
24aa8dccb170
Make XMPP actually work.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
5
diff
changeset
|
186 this.dom.removeChild(children[i]); |
5 | 187 } |
188 }; |