f164c5bd08e094cc382a5a8dd6f6a11c6a724746
[redakcja.git] / platforma / static / js / xslt.js
1 var MARGIN = {
2     dramat_wierszowany_l: 4,
3     dramat_wierszowany_lp: 4,
4     dramat_wspolczesny: 4,
5     wywiad: 4,
6     opowiadanie: 4,
7     powiesc: 4,
8     liryka_l: 4,
9     liryka_lp: 4,
10     naglowek_czesc: 4,
11     naglowek_akt: 4,
12     naglowek_rozdzial: 4,
13     naglowek_osoba: 4,
14     lista_osob: 4,
15     
16     akap: 3,
17     akap_cd: 3,
18     akap_dialog: 3,
19     strofa: 3,
20     motto: 3, 
21     miejsce_czas: 3,
22         
23     autor_utworu: 2,
24     nazwa_utworu: 2,
25     dzielo_nadrzedne: 2,
26     didaskalia: 2,
27     motto_podpis: 2,
28     naglowek_listy: 2,
29     
30     kwestia: 1,
31     lista_osoba: 1
32 }
33
34 MARGIN['rdf:RDF'] = 3;
35 MARGIN['rdf:Description'] = 2;
36
37 function elementType(element) {
38     if ($.inArray(element.tagName, ['akap', 'akap_cd', 'akap_dialog', 'strofa', 'didaskalia', 'wers', 'wers_cd', 'wers_akap', 'wers_wciety', 'autor_utworu', 'nazwa_utworu', 'dzielo_nadrzedne', 'podpis'])) {
39         return 'inline';
40     } else {
41         return 'block';
42     }
43 }
44
45 // Serializuje XML, wstawiając odpowiednie ilości białych znaków między elementami
46 function serialize(element, mode) {
47     if (!mode) {
48         mode = 'block';
49     }
50     
51     if (element.nodeType == 3) { // tekst
52         if (mode == 'block') {
53             return [$.trim(element.nodeValue)];
54         } else {
55             return [element.nodeValue];
56         }
57     } else if (element.nodeType != 1) { // pomijamy węzły nie będące elementami XML ani tekstem
58         return [];
59     }
60     
61     var result = [];
62     var hasContent = false;
63     
64     if (MARGIN[element.tagName]) {
65         for (var i=0; i < MARGIN[element.tagName]; i++) {
66             result.push('\n');
67         };
68     } else if (element.tagName.indexOf('dc:') != -1) {
69         result.push('\n');
70     }
71     
72     result.push('<');
73     result.push(element.tagName);
74     
75     // Mozilla nie uważa deklaracji namespace za atrybuty
76     var ns = element.tagName.indexOf(':');
77     if (ns != -1 && $.browser.mozilla) {
78         result.push(' xmlns:');
79         result.push(element.tagName.substring(0, ns));
80         result.push('="');
81         result.push(element.namespaceURI);
82         result.push('"');
83     }
84     
85     if (element.attributes) {
86         for (var i=0; i < element.attributes.length; i++) {
87             var attr = element.attributes[i];
88             result.push(' ');
89             result.push(attr.name);
90             result.push('="');
91             result.push(attr.value);
92             result.push('"');
93             hasContent = true;
94         }
95     }
96     
97     if (element.childNodes.length == 0) {
98         result.push(' />');
99     } else {
100         result.push('>');
101
102         for (var i=0; i < element.childNodes.length; i++) {
103             result = result.concat(serialize(element.childNodes[i], 
104                 mode == 'inline' ? 'inline' : elementType(element.childNodes[i])));
105         }
106
107         result.push('</');
108         result.push(element.tagName);
109         result.push('>');
110     }
111     
112     return result;
113 };
114
115
116 function createXSLT(xsl) {
117     var p = new XSLTProcessor();
118     p.importStylesheet(xsl);
119     return p;
120 }
121
122
123 var xml2htmlStylesheet = null;
124 var html2xmlStylesheet = null;
125
126
127 // Wykonuje block z załadowanymi arkuszami stylów
128 function withStylesheets(block, onError) {
129     if (xml2htmlStylesheet && html2xmlStylesheet) {
130         block();
131         return;
132     }
133     $.blockUI({message: 'Ładowanie arkuszy stylów...'});
134     $.ajax({
135         url: '/static/xsl/wl2html_client.xsl',
136         dataType: 'xml',
137         success: function(data) {
138             xml2htmlStylesheet = createXSLT(data);
139             $.ajax({
140                 url: '/static/xsl/html2wl_client.xsl',
141                 dataType: 'xml',
142                 success: function(data) {
143                     html2xmlStylesheet = createXSLT(data);
144                     $.unblockUI();
145                     block();
146                 },
147                 error: onError
148             })
149         },
150         error: onError
151     })
152 }
153
154 function transform(editor) {
155     $.blockUI({message: 'Ładowanie...'});
156     withStylesheets(function() {
157         setTimeout(function() {
158             var doc = null;
159             var parser = new DOMParser();
160             var serializer = new XMLSerializer();
161
162             doc = editor.getCode().replace(/\/\s+/g, '<br />');
163             doc = parser.parseFromString(doc, 'text/xml');
164             var error = $('parsererror', doc);
165             console.log(error);
166             if (error.length == 0) {
167                 doc = xml2htmlStylesheet.transformToFragment(doc, document);
168                 error = $('parsererror', doc);
169             }
170             console.log('xml', doc);
171             if (error.length > 0) {
172                 console.log(error);
173                 $('#html-view').html('<p class="error">Wystąpił błąd:</p><pre>' + error.text() + '</pre>');
174             } else {
175                 console.log('after transform', doc);
176                 $('#html-view').html(doc.firstChild);                          
177             }
178
179             $.unblockUI();
180         }, 200);
181     }, function() { alert('Nie udało się załadować XSLT!'); });
182 };
183
184
185 function reverseTransform(editor) {
186     $.blockUI({message: 'Ładowanie...'});
187     withStylesheets(function() {
188         setTimeout(function() {
189             var doc = null;
190             var parser = new DOMParser();
191             var serializer = new XMLSerializer();
192
193             if ($('#html-view .error').length > 0) {
194                 $('#source-editor').unblock();
195                 return;
196             }
197             
198             doc = serializer.serializeToString($('#html-view div').get(0))
199             doc = parser.parseFromString(doc, 'text/xml');
200             console.log('xml',doc, doc.documentElement);
201             // TODO: Sprawdzenie błędów
202             var error = $('parsererror', doc.documentElement);
203             console.log(error);
204             if (error.length == 0) {
205                 doc = html2xmlStylesheet.transformToDocument(doc, document);
206                 error = $('parsererror', doc.documentElement);
207             }
208             
209             if (error.length > 0) {
210                 console.log(error);
211                 $('#source-editor').html('<p>Wystąpił błąd:</p>' + error.text());
212             } else {
213                 doc = serialize(doc.documentElement).join('');
214                 editor.setCode(doc);                                
215             }
216             
217             console.log('after transform', doc, doc.documentElement);
218             $.unblockUI();
219         }, 200)
220     }, function() { alert('Nie udało się załadować XSLT!')});
221 };
222