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 };