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