7efcf32c104d6ccfad2232311a17b39e9e692e85
[redakcja.git] / platforma / static / js / main.js
1 // Serializuje XML, wstawiając odpowiednie ilości białych znaków między elementami
2 function serialize(element) {
3     if (element.nodeType == 3) { // tekst
4         return [$.trim(element.nodeValue)];
5     } else if (element.nodeType != 1) { // pomijamy węzły nie będące elementami XML ani tekstem
6         return [];
7     }
8     
9     var result = [];
10     var hasContent = false;
11     
12     result.push('<');
13     result.push(element.tagName);
14     
15     // Mozilla nie uważa deklaracji namespace za atrybuty
16     var ns = element.tagName.indexOf(':');
17     if (ns != -1 && $.browser.mozilla) {
18         result.push(' xmlns:');
19         result.push(element.tagName.substring(0, ns));
20         result.push('="');
21         result.push(element.namespaceURI);
22         result.push('"');
23     }
24     
25     if (element.attributes) {
26         for (var i=0; i < element.attributes.length; i++) {
27             var attr = element.attributes[i];
28             result.push(' ');
29             result.push(attr.name);
30             result.push('="');
31             result.push(attr.value);
32             result.push('"');
33             hasContent = true;
34         }
35     }
36     
37     if (element.childNodes.length == 0) {
38         result.push(' />');
39     } else {
40         result.push('>');
41
42         for (var i=0; i < element.childNodes.length; i++) {
43             result = result.concat(serialize(element.childNodes[i]));
44         }
45
46         result.push('</');
47         result.push(element.tagName);
48         result.push('>');
49     }
50     
51     if (element.tagName == 'akap' || element.tagName == 'akap_dialog' || element.tagName == 'akap_cd') {
52         result.push('\n\n\n');
53     } else if (element.tagName == 'rdf:RDF') {
54         result.push('\n\n\n\n\n');
55     } else if (element.tagName.indexOf('dc:') != -1) {
56         result.push('\n');
57     }
58     
59     return result;
60 };
61
62
63 // Teraz nieużywane
64 function highlight(colour) {
65     var range, sel;
66     if (window.getSelection) {
67         // Non-IE case
68         sel = window.getSelection();
69         if (sel.getRangeAt) {
70             range = sel.getRangeAt(0);
71         }
72         document.designMode = "on";
73         if (range) {
74             sel.removeAllRanges();
75             sel.addRange(range);
76         }
77         // Use HiliteColor since some browsers apply BackColor to the whole block
78         if ( !document.execCommand("HiliteColor", false, colour) ) {
79             document.execCommand("BackColor", false, colour);
80         }
81         document.designMode = "off";
82     } else if (document.selection && document.selection.createRange) {
83         // IE case
84         range = document.selection.createRange();
85         range.execCommand("BackColor", false, colour);
86     }
87 }
88
89 // function unselectThemes(themeId) {
90 //     $('.Apple-style-span').each(function() {
91 //         $(this).after($(this).html());
92 //         $(this).remove();
93 //     });
94 // }
95
96 function gallery(element) {
97     var element = $(element);
98     var imageDimensions = {};
99     
100     function changePage(pageNumber) {        
101         $('img', element).attr('src', element.data('images')[pageNumber - 1]);
102     }
103     
104     function normalizeNumber(pageNumber) {
105         // Numer strony musi być pomiędzy 1 a najwyższym numerem
106         var pageCount = element.data('images').length;
107         pageNumber = parseInt(pageNumber, 10);
108         
109         if (!pageNumber || pageNumber == NaN || pageNumber == Infinity || pageNumber == -Infinity) {
110             return 1;
111         } else if (pageNumber < 1) {
112             return 1;
113         } else if (pageNumber > pageCount) {
114             return pageCount;
115         } else {
116             return pageNumber;
117         }
118     }
119     
120     $.ajax({
121         url: '/gallery/sample',
122         type: 'GET',
123         dataType: 'json',
124     
125         success: function(data) {
126             element.data('images', data);
127             var pn = $('.page-number', element);
128             pn.change(function(event) {
129                 console.log('change!', $(this).val());
130                 event.preventDefault();
131                 var n = normalizeNumber(pn.val());
132                 pn.val(n);
133                 changePage(n);
134             });
135             $('.previous-page', element).click(function() {
136                 pn.val(normalizeNumber(pn.val()) - 1);
137                 pn.change();
138             });
139             $('.next-page', element).click(function() {
140                 pn.val(normalizeNumber(pn.val()) + 1);
141                 pn.change();
142             });
143             
144             
145             var image = $('img', element).attr('unselectable', 'on');
146             var origin = {};
147             var imageOrigin = {};
148             var zoomFactor = 1;
149             
150             $('.zoom-in', element).click(function() {
151                 zoomFactor = Math.min(2, zoomFactor + 0.2);
152                 zoom();
153             });
154             $('.zoom-out', element).click(function() {
155                 zoomFactor = Math.max(0.2, zoomFactor - 0.2);
156                 zoom();
157             });
158             
159             $('img', element).load(function() {
160                 image.css({width: null, height: null});
161                 imageDimensions = {
162                     width: $(this).width() * zoomFactor,
163                     height: $(this).height() * zoomFactor,
164                     originWidth: $(this).width(),
165                     originHeight: $(this).height(),
166                     galleryWidth: $(this).parent().width(),
167                     galleryHeight: $(this).parent().height()
168                 };
169                 console.log('load', imageDimensions)
170                 var position = normalizePosition(
171                     image.position().left,
172                     image.position().top, 
173                     imageDimensions.galleryWidth,
174                     imageDimensions.galleryHeight,
175                     imageDimensions.width,
176                     imageDimensions.height
177                 );
178                 image.css({left: position.x, top: position.y, width: $(this).width() * zoomFactor, height: $(this).height() * zoomFactor});
179             });
180
181             $(window).resize(function() {
182                 imageDimensions.galleryWidth = image.parent().width();
183                 imageDimensions.galleryHeight = image.parent().height();
184             });
185             
186             function bounds(galleryWidth, galleryHeight, imageWidth, imageHeight) {
187                 return {
188                     maxX: 0,
189                     maxY: 0,
190                     minX: galleryWidth - imageWidth,
191                     minY: galleryHeight - imageHeight
192                 }
193             }
194             
195             function normalizePosition(x, y, galleryWidth, galleryHeight, imageWidth, imageHeight) {
196                 var b = bounds(galleryWidth, galleryHeight, imageWidth, imageHeight);
197                 return {
198                     x: Math.min(b.maxX, Math.max(b.minX, x)),
199                     y: Math.min(b.maxY, Math.max(b.minY, y))
200                 }
201             }
202             
203             function onMouseMove(event) {
204                 var position = normalizePosition(
205                     event.clientX - origin.x + imageOrigin.left,
206                     event.clientY - origin.y + imageOrigin.top, 
207                     imageDimensions.galleryWidth,
208                     imageDimensions.galleryHeight,
209                     imageDimensions.width,
210                     imageDimensions.height
211                 );
212                 image.css({position: 'absolute', top: position.y, left: position.x});
213                 return false;
214             }
215             
216             function setZoom(factor) {
217                 zoomFactor = factor;
218             }
219             
220             function zoom() {
221                 imageDimensions.width = imageDimensions.originWidth * zoomFactor;
222                 imageDimensions.height = imageDimensions.originHeight * zoomFactor;
223                 var position = normalizePosition(
224                     image.position().left,
225                     image.position().top, 
226                     imageDimensions.galleryWidth,
227                     imageDimensions.galleryHeight,
228                     imageDimensions.width,
229                     imageDimensions.height
230                 );
231                 console.log(image.position(), imageDimensions, position);
232                 image.css({width: imageDimensions.width, height: imageDimensions.height,
233                     left: position.x, top: position.y});
234
235             }
236             
237             window.setZoom = setZoom;
238             
239             function onMouseUp(event) {
240                 $(document)
241                     .unbind('mousemove.gallery')
242                     .unbind('mouseup.gallery');
243                 return false;
244             }
245             
246             image.bind('mousedown', function(event) {
247                 origin = {
248                     x: event.clientX,
249                     y: event.clientY
250                 };
251                 imageOrigin = image.position();
252                 $(document)
253                     .bind('mousemove.gallery', onMouseMove)
254                     .bind('mouseup.gallery', onMouseUp);
255                 return false;
256             });
257         }
258     });
259 }
260
261
262 function html(element) {
263     var element = $(element);
264     
265     function selectTheme(themeId)
266     {
267         var selection = window.getSelection();
268
269         // remove current selection
270         selection.removeAllRanges();
271
272         var range = document.createRange();
273         var s = $(".motyw[theme-class='"+themeId+"']")[0];
274         var e = $(".end[theme-class='"+themeId+"']")[0];
275         // console.log('Selecting range:', themeId, range, s, e);
276
277         if(s && e) {
278             range.setStartAfter(s);
279             range.setEndBefore(e);
280             selection.addRange(range);
281             // highlight('yellow');
282             // selection.removeAllRanges();
283         }
284     };
285     
286     var button = $('<button class="edit-button">Edytuj</button>');
287     $(element).bind('mousemove', function(event) {
288         var editable = $(event.target).closest('*[x-editable]');
289         $('.active[x-editable]', element).not(editable).removeClass('active').children('.edit-button').remove();
290         if (!editable.hasClass('active')) {
291             editable.addClass('active').append(button);
292         }
293     });
294
295     $('.motyw').live('click', function() {
296         selectTheme($(this).attr('theme-class'));
297     });
298 }
299
300
301 $(function() {
302     gallery('#sidebar');
303     html('#html-view');
304     
305     CodeMirror.fromTextArea('id_text', {
306         parserfile: 'parsexml.js',
307         path: "/static/js/lib/codemirror/",
308         stylesheet: "/static/css/xmlcolors.css",
309         parserConfig: {
310             useHTMLKludges: false
311         },
312         iframeClass: 'xml-iframe',
313         textWrapping: true,
314         tabMode: 'spaces',
315         indentUnit: 0,
316         initCallback: function(editor) {
317             
318             function createXSLT(xsl) {
319                 var p = new XSLTProcessor();
320                 p.importStylesheet(xsl);
321                 return p;
322             }
323
324             function transform() {
325                 $.ajax({
326                     url: '/static/xsl/wl2html_client.xsl',
327                     dataType: 'xml',
328                     success: function(data) {
329                         var doc = null;
330                         var parser = new DOMParser();
331                         var serializer = new XMLSerializer();
332                         var htmlXSL = createXSLT(data);
333
334                         doc = editor.getCode().replace(/\/\s+/g, '<br />');
335                         doc = parser.parseFromString(doc, 'text/xml');
336                         console.log('xml', doc);
337                         doc = htmlXSL.transformToFragment(doc, document);
338                         console.log('after transform', doc);
339                         $('#html-view').html(doc.firstChild);
340                     },
341                     error: function() {alert('Error loading XSL!')}
342                 });        
343             };
344
345             function reverseTransform () {
346                 $.ajax({
347                     url: '/static/xsl/html2wl_client.xsl',
348                     dataType: 'xml',
349                     success: function(data) {
350                         var doc = null;
351                         var parser = new DOMParser();
352                         var serializer = new XMLSerializer();
353                         var xsl = createXSLT(data);
354
355                         doc = serializer.serializeToString($('#html-view div').get(0))
356                         doc = parser.parseFromString(doc, 'text/xml');
357                         console.log('xml',doc, doc.documentElement);
358                         // TODO: Sprawdzenie błędów
359                         doc = xsl.transformToDocument(doc);
360                         console.log('after transform', doc, doc.documentElement);
361                         doc = serialize(doc.documentElement).join('');
362                         // doc = serializer.serializeToString(doc.documentElement)
363                         editor.setCode(doc);
364                     },
365                     error: function() {alert('Error loading XSL!')}
366                 });
367             };
368
369             $('#save-button').click(function(event) {
370                 event.preventDefault();
371                 console.log(editor.getCode(), $('form input[name=text]').get(0));
372                 $('form textarea[name=text]').val(editor.getCode());
373                 $('form').ajaxSubmit(function() {
374                     alert('Udało się!');
375                 });
376             });
377
378             $('#simple-view-tab').click(function() {
379                 if ($(this).hasClass('active')) {
380                     return;
381                 }
382                 $(this).addClass('active');
383                 $('#source-view-tab').removeClass('active');
384                 $('#source-editor').hide();
385                 $('#simple-editor').show();
386                 transform();
387             });
388
389             $('#source-view-tab').click(function() {
390                 if ($(this).hasClass('active')) {
391                     return;
392                 }
393                 $(this).addClass('active');
394                 $('#simple-view-tab').removeClass('active');
395                 $('#simple-editor').hide();
396                 $('#source-editor').show();
397                 reverseTransform();
398             });
399
400             $('.toolbar button').click(function(event) {
401                 event.preventDefault();
402                 var params = eval("(" + $(this).attr('ui:action-params') + ")");
403                 scriptletCenter.scriptlets[$(this).attr('ui:action')](editor, params);
404             });
405
406             $('.toolbar select').change(function() {
407                 var slug = $(this).val();
408
409                 $('.toolbar-buttons-container').hide().filter('[data-group=' + slug + ']').show();
410                 $(window).resize();
411             });
412
413             $('.toolbar-buttons-container').hide();
414             $('.toolbar select').change();
415
416             $('#simple-view-tab').click();
417         }
418     });
419     
420     $(window).resize(function() {
421         $('iframe').height($(window).height() - $('#tabs').outerHeight() - $('#source-editor .toolbar').outerHeight());
422     });
423     
424     $(window).resize();
425     
426     $('.vsplitbar').click(function() {
427         if ($('#sidebar').width() == 0) {
428             $('#sidebar').width(480).css({right: 0}).show();
429             $('#source-editor, #simple-editor').css({right: 495});
430             $('.vsplitbar').css({right: 480})
431             // $('#splitter').trigger('resize', [$(window).width() - 480]);
432         } else {
433             $('#sidebar').width(0).hide();
434             $('#source-editor, #simple-editor').css({right: 15});
435             $('.vsplitbar').css({right: 0});
436             // $('#splitter').trigger('resize', [$(window).width()]);
437         }
438         $(window).resize();
439     });
440                 
441
442 });