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