Fixes #382.
[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 var blockTags = ['akap', 'akap_cd', 'akap_dialog', 'strofa', 'didaskalia', 'wers', 'wers_cd', 'wers_akap', 'wers_wciety', 'autor_utworu', 'nazwa_utworu', 'dzielo_nadrzedne', 'podpis'];
38 function elementType(element) {
39     if (blockTags.indexOf(element.tagName) != -1) {
40         return 'inline';
41     } else {
42         return 'block';
43     }
44 }
45
46 // Serializuje XML, wstawiając odpowiednie ilości białych znaków między elementami
47 function serialize(element, mode) {
48     if (!mode) {
49         mode = 'block';
50     }
51     
52     if (element.nodeType == 3) { // tekst
53         return [element.nodeValue];        
54     } else if (element.nodeType != 1) { // pomijamy węzły nie będące elementami XML ani tekstem
55         return [];
56     }
57     
58     var result = [];
59     var hasContent = false;
60     
61     
62     
63     if (MARGIN[element.tagName]) {
64         for (var i=0; i < MARGIN[element.tagName]; i++) {
65             result.push('\n');
66         };
67     } else if (element.tagName.indexOf('dc:') != -1) {
68         result.push('\n');
69     }
70     
71     result.push('<');
72     result.push(element.tagName);
73     
74     // Mozilla nie uważa deklaracji namespace za atrybuty
75     var ns = element.tagName.indexOf(':');
76     if (ns != -1 && $.browser.mozilla) {
77         result.push(' xmlns:');
78         result.push(element.tagName.substring(0, ns));
79         result.push('="');
80         result.push(element.namespaceURI);
81         result.push('"');
82     }
83     
84     if (element.attributes) {
85         for (var i=0; i < element.attributes.length; i++) {
86             var attr = element.attributes[i];
87             result.push(' ');
88             result.push(attr.name);
89             result.push('="');
90             result.push(attr.value);
91             result.push('"');
92             hasContent = true;
93         }
94     }
95     
96     if (element.childNodes.length == 0) {
97         result.push(' />');
98     } else {
99         result.push('>');
100
101         for (var i=0; i < element.childNodes.length; i++) {
102             result = result.concat(serialize(element.childNodes[i], 
103                 mode == 'inline' ? 'inline' : elementType(element.childNodes[i])));
104         }
105
106         result.push('</');
107         result.push(element.tagName);
108         result.push('>');
109     }
110     
111     return result;
112 };
113
114
115 function createXSLT(xsl) {
116     var p = new XSLTProcessor();
117     p.importStylesheet(xsl);
118     return p;
119 }
120
121
122 var xml2htmlStylesheet = null;
123 var html2xmlStylesheet = null;
124
125
126 // Wykonuje block z załadowanymi arkuszami stylów
127 function withStylesheets(block, onError) {
128     if (xml2htmlStylesheet && html2xmlStylesheet) {
129         block();
130         return;
131     }
132     $.blockUI({message: 'Ładowanie arkuszy stylów...'});
133     $.ajax({
134         url: STATIC_URL + 'xsl/wl2html_client.xsl',
135         dataType: 'xml',
136         success: function(data) {
137             xml2htmlStylesheet = createXSLT(data);
138             $.ajax({
139                 url: STATIC_URL + 'xsl/html2wl_client.xsl',
140                 dataType: 'xml',
141                 success: function(data) {
142                     html2xmlStylesheet = createXSLT(data);
143                     $.unblockUI();
144                     block();
145                 },
146                 error: onError
147             })
148         },
149         error: onError
150     })
151 }
152
153
154 function xml2html(options) {
155     withStylesheets(function() {
156         var xml = options.xml.replace(/\/\s+/g, '<br />');
157         var parser = new DOMParser();
158         var serializer = new XMLSerializer();
159         var doc = parser.parseFromString(xml, 'text/xml');
160         var error = $('parsererror', doc);
161         
162         if (error.length == 0) {
163             doc = xml2htmlStylesheet.transformToFragment(doc, document);
164             error = $('parsererror', doc);
165         }
166         
167         if (error.length > 0 && options.error) {
168             options.error(error.text());
169         } else {
170             options.success(doc.firstChild);
171         }
172     }, function() { options.error && options.error('Nie udało się załadować XSLT'); });
173 }
174
175
176 function html2xml(options) {
177     withStylesheets(function() {
178         var xml = options.xml;
179         var parser = new DOMParser();
180         var serializer = new XMLSerializer();
181         var doc = parser.parseFromString(xml, 'text/xml');
182         var error = $('parsererror', doc.documentElement);
183
184         if (error.length == 0) {
185             doc = html2xmlStylesheet.transformToDocument(doc);
186             error = $('parsererror', doc.documentElement);
187         }
188         
189         if (error.length > 0 && options.error) {
190             options.error(error.text());
191         } else {
192             if (options.inner) {
193                 var result = [];
194                 for (var i = 0; i < doc.documentElement.childNodes.length; i++) {
195                     result.push(serialize(doc.documentElement.childNodes[i]).join(''));
196                 };
197                 options.success(result.join(''));
198             } else {
199                 options.success(serialize(doc.documentElement).join(''));
200             }
201         }
202     }, function() { options.error && options.error('Nie udało się załadować XSLT'); });
203 };
204